﻿///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2023, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются 
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////

#Область ПрограммныйИнтерфейс

// Для вызова из обработчика ПриНачальномЗаполненииЭлементов.
// Заполняет колонки с именами ИмяРеквизита_<КодЯзыка> текстовыми значениями для указанных кодов языков.
//
// Параметры:
//  Элемент        - СтрокаТаблицыЗначений - заполняемая строка таблицы с колонками ИмяРеквизита_КодЯзыка.
//  ИмяРеквизита   - Строка - имя реквизита. Например, "Наименование"
//  ИсходнаяСтрока - Строка - строка в формате НСтр. Например, "ru = 'Сообщение на русском'; en = 'English message'".
//  КодыЯзыков     - Массив - коды языков, на которых нужно заполнить строки.
// 
// Пример:
//
//  МультиязычностьСервер.ЗаполнитьМультиязычныйРеквизит(Элемент, "Наименование", "ru = 'Сообщение на русском'; en =
//  'English message'", КодыЯзыков);
//
Процедура ЗаполнитьМультиязычныйРеквизит(Элемент, ИмяРеквизита, ИсходнаяСтрока, КодыЯзыков = Неопределено) Экспорт
	
	Для каждого КодЯзыка Из КодыЯзыков Цикл
		
		ЗначениеПоКодуЯзыка = НСтр(ИсходнаяСтрока, КодЯзыка);
		ЗначениеДляЗаполнения = ?(ЗначениеЗаполнено(ЗначениеПоКодуЯзыка), ЗначениеПоКодуЯзыка, НСтр(ИсходнаяСтрока, ОбщегоНазначения.КодОсновногоЯзыка()));
		Элемент[ИмяЛокализуемогоРеквизита(ИмяРеквизита, КодЯзыка)] = ЗначениеДляЗаполнения;
		Если СтрСравнить(КодЯзыка, ОбщегоНазначения.КодОсновногоЯзыка()) = 0 Тогда
			Элемент[ИмяРеквизита] = ЗначениеДляЗаполнения;
		КонецЕсли;
	КонецЦикла;
	
КонецПроцедуры

// Вызывается из обработчика ПриСозданииНаСервере формы объекта. Добавляет кнопку открытия в поля ввода
// мультиязычных реквизитов на этой форме. Нажатие кнопки открывает окно ввода значения реквизита на всех
// имеющихся в конфигурации языках.
//
// Параметры:
//   Форма  - ФормаКлиентскогоПриложения - форма объекта.
//   Объект - ДанныеФормыСтруктура:
//     * Ссылка - ЛюбаяСсылка
//  ИмяОбъекта - Строка - для форм списка имя динамического списка на форме. По умолчанию, "Список".
//                        Для других форм имя основного реквизита на форме. Следует использовать,
//                        если имя отличается от стандартных: "Объект", "Запись", "Список".
//
Процедура ПриСозданииНаСервере(Форма, Объект = Неопределено, ИмяОбъекта = Неопределено) Экспорт
	
	Если Объект = Неопределено Тогда
		ТипФормы = МультиязычностьПовтИсп.ОпределитьТипФормы(Форма.ИмяФормы);
		Если ТипФормы = "ОсновнаяФормаСписка" Или ТипФормы = "ОсновнаяФормаВыбора" Тогда
			Если ТипЗнч(ИмяОбъекта) <> Тип("Строка") Тогда
				ИмяОбъекта = "Список";
			КонецЕсли;
			
			ИзменениеТекстаЗапросаСпискаДляТекущегоЯзыка(Форма, ИмяОбъекта);
		КонецЕсли;
		Возврат;
	КонецЕсли;
	
	ИспользуютсяДополнительныеЯзыки = Ложь;
	Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.Мультиязычность.Печать") Тогда
		МодульУправлениеПечатьюМультиязычность = ОбщегоНазначения.ОбщийМодуль("УправлениеПечатьюМультиязычность");
		ИспользуютсяДополнительныеЯзыки = МодульУправлениеПечатьюМультиязычность.ИспользуютсяДополнительныеЯзыкиПечатныхФорм();
	КонецЕсли;
	
	Если Объект <> Неопределено
		И МультиязычностьПовтИсп.КонфигурацияИспользуетТолькоОдинЯзык(Объект.Свойство("Представления"))
		И Не ИспользуютсяДополнительныеЯзыки Тогда
		Возврат;
	КонецЕсли;
	
	СписокРеквизитовФормы = Форма.ПолучитьРеквизиты();
	СоздатьПараметрыМультиязычныхРеквизитов = Истина;
	Для Каждого Реквизит Из СписокРеквизитовФормы Цикл
		Если Реквизит.Имя = "ПараметрыМультиязычныхРеквизитов" Тогда
			СоздатьПараметрыМультиязычныхРеквизитов = Ложь;
		КонецЕсли;
	КонецЦикла;
	
	Если СоздатьПараметрыМультиязычныхРеквизитов Тогда
		ДобавляемыеРеквизиты = Новый Массив;
		ДобавляемыеРеквизиты.Добавить(Новый РеквизитФормы("ПараметрыМультиязычныхРеквизитов", Новый ОписаниеТипов(),,, Истина));
		Форма.ИзменитьРеквизиты(ДобавляемыеРеквизиты);
	КонецЕсли;
	
	Форма.ПараметрыМультиязычныхРеквизитов = Новый Структура;
	
	ОбъектМетаданные = ОбъектМетаданных(Объект);

	Если ТипЗнч(ИмяОбъекта) <> Тип("Строка") Тогда
		ИмяОбъекта = ?(ОбщегоНазначения.ЭтоРегистр(ОбъектМетаданные), "Запись", "Объект");
	КонецЕсли;
	
	НаименованияРеквизитов = НаименованияЛокализуемыхРеквизитовОбъекта(ОбъектМетаданные, ИмяОбъекта + ".");
	
	Для каждого Элемент Из Форма.Элементы Цикл
		
		Если ТипЗнч(Элемент) = Тип("ПолеФормы") И НаименованияРеквизитов[Элемент.ПутьКДанным] <> Неопределено Тогда
			Элемент.КнопкаОткрытия = Истина;
			Элемент.УстановитьДействие("Открытие", "Подключаемый_Открытие");
			Форма.ПараметрыМультиязычныхРеквизитов.Вставить(Элемент.Имя, Элемент.ПутьКДанным);
		КонецЕсли;
		
	КонецЦикла;
	
	Если Форма.Параметры.Свойство("ЗначениеКопирования")
		 И ЗначениеЗаполнено(Форма.Параметры.ЗначениеКопирования) Тогда
			
			ОчиститьМультиязычныеРеквизиты(Объект, ОбъектМетаданные);
			ПриЧтенииПредставленийНаСервере(Объект);
			
	КонецЕсли;
	
КонецПроцедуры

// Вызывается из обработчика ПриЧтениеНаСервере формы объекта для заполнения значений мультиязычных
// реквизитов формы на текущем языке пользователя.
//
// Параметры:
//  Форма         - ФормаКлиентскогоПриложения - форма объекта.
//  ТекущийОбъект - Произвольный - объект, который был получен в обработчике формы ПриЧтенииНаСервере.
//  ИмяОбъекта - Строка - имя основного реквизита на форме. Следует использовать,
//                        если имя отличается от стандартных: "Объект", "Запись", "Список".
//
Процедура ПриЧтенииНаСервере(Форма, ТекущийОбъект, ИмяОбъекта = Неопределено) Экспорт
	
	ОбъектМетаданных = ОбъектМетаданных(ТекущийОбъект);
	Если ЭтоОсновнойЯзык() И МультиязычныеСтрокиВРеквизитах(ОбъектМетаданных) Тогда
		Возврат;
	КонецЕсли;
	
	Если ОбщегоНазначения.ЭтоРегистр(ОбъектМетаданных) Тогда
		ПриЧтенииПредставленийНаСервере(ТекущийОбъект);
		Если ТипЗнч(ИмяОбъекта) <> Тип("Строка") Тогда
			ИмяОбъекта = "Запись";
		КонецЕсли;
	Иначе
		Если ТипЗнч(ИмяОбъекта) <> Тип("Строка") Тогда
			ИмяОбъекта = "Объект";
		КонецЕсли;
		ТекущийОбъект.ПриЧтенииПредставленийНаСервере();
	КонецЕсли;
	
	Форма.ЗначениеВРеквизитФормы(ТекущийОбъект, ИмяОбъекта);
	
КонецПроцедуры

// Вызывается из обработчика ПередЗаписьюНаСервере формы объекта или при программной записи объекта
// для записи значений мультиязычных реквизитов в соответствии с текущим языком пользователя.
//
// Параметры:
//  ТекущийОбъект - БизнесПроцессОбъект
//                - ДокументОбъект
//                - ЗадачаОбъект
//                - ПланВидовРасчетаОбъект
//                - ПланВидовХарактеристикОбъект
//                - ПланОбменаОбъект
//                - ПланСчетовОбъект
//                - СправочникОбъект - записываемый объект.
//
Процедура ПередЗаписьюНаСервере(ТекущийОбъект) Экспорт
	
	ОбъектМетаданных = ОбъектМетаданных(ТекущийОбъект);
	СуффиксТекущегоЯзыка = СуффиксТекущегоЯзыка();
	
	ИменаМультиязычныхРеквизитовВШапке = Новый Соответствие;
	
	Если МультиязычныеСтрокиВРеквизитах(ОбъектМетаданных) Тогда
		
		Если Не ОбщегоНазначения.ЭтоРегистр(ОбъектМетаданных) И ТекущийОбъект.ЭтоНовый()  Тогда
			
			ИменаМультиязычныхРеквизитовВШапке = НаименованияЛокализуемыхРеквизитовОбъектаВШапке(ОбъектМетаданных);
			
			Для Каждого Реквизит Из ИменаМультиязычныхРеквизитовВШапке Цикл
				
				ЗначениеРеквизита = ТекущийОбъект[Реквизит.Ключ];
				Если ПустаяСтрока(ЗначениеРеквизита) Тогда
					Продолжить;
				КонецЕсли;
				
				Если ПустаяСтрока(ТекущийОбъект[Реквизит.Ключ + "Язык1"]) Тогда
					ТекущийОбъект[Реквизит.Ключ + "Язык1"] = ЗначениеРеквизита;
				КонецЕсли;
				
				Если ПустаяСтрока(ТекущийОбъект[Реквизит.Ключ + "Язык2"]) Тогда
					ТекущийОбъект[Реквизит.Ключ + "Язык2"] = ЗначениеРеквизита;
				КонецЕсли;
				
			КонецЦикла;
			
		КонецЕсли;
		
		Если ТекущийЯзык().КодЯзыка = ОбщегоНазначения.КодОсновногоЯзыка() Тогда
			Возврат;
		КонецЕсли;
		
		ИменаМультиязычныхРеквизитовВШапке = НаименованияЛокализуемыхРеквизитовОбъектаВШапке(ОбъектМетаданных);
		
		Для Каждого Реквизит Из ИменаМультиязычныхРеквизитовВШапке Цикл
			
			Значение = ТекущийОбъект[Реквизит.Ключ];
			ТекущийОбъект[Реквизит.Ключ] = ТекущийОбъект[Реквизит.Ключ + СуффиксТекущегоЯзыка];
			ТекущийОбъект[Реквизит.Ключ + СуффиксТекущегоЯзыка] = Значение;
			
		КонецЦикла;
		
	КонецЕсли;
	
	Если Не ОбъектСодержитТЧПредставления(ОбъектМетаданных.ПолноеИмя()) Тогда
		Возврат;
	КонецЕсли;
	
	Реквизиты = Новый Массив;
	Для каждого Реквизит Из ТекущийОбъект.Ссылка.Метаданные().ТабличныеЧасти.Представления.Реквизиты Цикл
		Если СтрСравнить(Реквизит.Имя, "КодЯзыка") = 0 Тогда
			Продолжить;
		КонецЕсли;
		
		Реквизиты.Добавить(Реквизит.Имя);
	КонецЦикла;
	
	Представления = ТекущийОбъект.Представления; // ТабличнаяЧасть
	Отбор = Новый Структура();
	Отбор.Вставить("КодЯзыка", ТекущийЯзык().КодЯзыка);
	НайденныеСтроки = Представления.НайтиСтроки(Отбор);
	
	Если НайденныеСтроки.Количество() > 0 Тогда
		Представление = НайденныеСтроки[0];
	Иначе
		Представление = Представления.Добавить();
		Представление.КодЯзыка = ТекущийЯзык().КодЯзыка;
	КонецЕсли;
	
	Для каждого ИмяРеквизита Из Реквизиты Цикл
		
		Если ИменаМультиязычныхРеквизитовВШапке[ИмяРеквизита] <> Неопределено Тогда
			
			ЗначениеНаТекущемЯзыке = ТекущийОбъект[ИмяРеквизита + СуффиксТекущегоЯзыка];
			Если ПустаяСтрока(ЗначениеНаТекущемЯзыке) Тогда
				Представление[ИмяРеквизита] = ТекущийОбъект[ИмяРеквизита];
			Иначе
				Представление[ИмяРеквизита] = ЗначениеНаТекущемЯзыке;
			КонецЕсли;
			
		Иначе
			
			Представление[ИмяРеквизита] = ТекущийОбъект[ИмяРеквизита];
			
		КонецЕсли;
		
	КонецЦикла;
	
	Отбор.КодЯзыка = ОбщегоНазначения.КодОсновногоЯзыка();
	НайденныеСтроки = Представления.НайтиСтроки(Отбор);
	Если НайденныеСтроки.Количество() > 0 Тогда
		Для каждого ИмяРеквизита Из Реквизиты Цикл  
			Если ИменаМультиязычныхРеквизитовВШапке[ИмяРеквизита] = Неопределено
			   Или (ТекущийЯзык().КодЯзыка <> ОбщегоНазначения.КодОсновногоЯзыка()
			   И ПустаяСтрока(СуффиксТекущегоЯзыка)) Тогда
				ТекущийОбъект[ИмяРеквизита] = НайденныеСтроки[0][ИмяРеквизита]; 
			КонецЕсли;
		КонецЦикла;
		Представления.Удалить(НайденныеСтроки[0]);
	КонецЕсли;
	
	Представления.Свернуть("КодЯзыка", СтрСоединить(Реквизиты, ","));
	
	Если ИменаМультиязычныхРеквизитовВШапке.Количество() > 0 Тогда
		СкопироватьМультиязычныеЗначенияВРеквизитыШапки(ТекущийОбъект, ИменаМультиязычныхРеквизитовВШапке, КодПервогоДополнительногоЯзыкаИнформационнойБазы());
		СкопироватьМультиязычныеЗначенияВРеквизитыШапки(ТекущийОбъект, ИменаМультиязычныхРеквизитовВШапке, КодВторогоДополнительногоЯзыкаИнформационнойБазы());
	КонецЕсли;
	
КонецПроцедуры

// Вызывается из модуля объекта для заполнения значений мультиязычных
// реквизитов объекта на текущем языке пользователя.
//
// Параметры:
//  Объект - БизнесПроцессОбъект
//         - ДокументОбъект
//         - ЗадачаОбъект
//         - ПланВидовРасчетаОбъект
//         - ПланВидовХарактеристикОбъект
//         - ПланОбменаОбъект
//         - ПланСчетовОбъект
//         - СправочникОбъект - объект данных.
//
Процедура ПриЧтенииПредставленийНаСервере(Объект) Экспорт
	
	ОбъектМетаданных = ОбъектМетаданных(Объект);
	
	Если ЭтоОсновнойЯзык() Тогда
		Возврат;
	КонецЕсли;
	
	СуффиксТекущегоЯзыка = СуффиксТекущегоЯзыка();

	ИменаЛокализуемыхРеквизитов = НаименованияЛокализуемыхРеквизитовОбъектаВШапке(ОбъектМетаданных);
	
	Если МультиязычныеСтрокиВРеквизитах(ОбъектМетаданных) И ЗначениеЗаполнено(СуффиксТекущегоЯзыка) Тогда
		
		Для Каждого Реквизит Из ИменаЛокализуемыхРеквизитов Цикл
			
			Значение = Объект[Реквизит.Ключ];
			Объект[Реквизит.Ключ] = Объект[Реквизит.Ключ + СуффиксТекущегоЯзыка];
			Объект[Реквизит.Ключ + СуффиксТекущегоЯзыка] = Значение;
			
			Если ПустаяСтрока(Объект[Реквизит.Ключ]) Тогда
				Объект[Реквизит.Ключ] = Значение;
			КонецЕсли;
			
		КонецЦикла;
		
	КонецЕсли;
	
	Если Не ОбъектСодержитТЧПредставления(ОбъектМетаданных.ПолноеИмя()) Тогда
		Возврат;
	КонецЕсли;
	
	Для каждого Реквизит Из ОбъектМетаданных.ТабличныеЧасти.Представления.Реквизиты Цикл
		
		Если СтрСравнить(Реквизит.Имя, "КодЯзыка") = 0 Тогда
			Продолжить;
		КонецЕсли;
		
		ИмяРеквизита = Реквизит.Имя;
		
		Отбор = Новый Структура();
		Отбор.Вставить("КодЯзыка", ОбщегоНазначения.КодОсновногоЯзыка());
		НайденныеСтроки = Объект.Представления.НайтиСтроки(Отбор);
	
		Если НайденныеСтроки.Количество() > 0 Тогда
			
			Представление = НайденныеСтроки[0];
			
		Иначе
			
			Если ПустаяСтрока(Объект[ИмяРеквизита]) Тогда
				Продолжить;
			КонецЕсли;
			
			Представление = Объект.Представления.Добавить();
			Представление.КодЯзыка = ОбщегоНазначения.КодОсновногоЯзыка();
			
		КонецЕсли;
		Представление[ИмяРеквизита] = Объект[ИмяРеквизита];
		
		Отбор = Новый Структура();
		Отбор.Вставить("КодЯзыка", ТекущийЯзык().КодЯзыка);
		НайденныеСтроки = Объект.Представления.НайтиСтроки(Отбор);
		
		Если НайденныеСтроки.Количество() > 0 И ЗначениеЗаполнено(НайденныеСтроки[0][ИмяРеквизита]) Тогда
			Объект[ИмяРеквизита] = НайденныеСтроки[0][ИмяРеквизита];
		КонецЕсли;
		
	КонецЦикла;
	
КонецПроцедуры

// Вызывается из обработчика ОбработкаПолученияДанныхВыбора для формирования списка при вводе по строке,
// автоподборе текста и быстром выбора, а также при выполнении метода ПолучитьДанныеВыбора.
// Список содержит варианты на всех языках с учетом реквизитов определенных в свойстве ВводПоСтроке.
//
// Параметры:
//  ДанныеВыбора         - СписокЗначений - данные для выбора.
//  Параметры            - Структура - содержит параметры выбора.
//  СтандартнаяОбработка - Булево  - данный параметр передается признак выполнения стандартной (системной) обработки события.
//  ОбъектМетаданных     - ОбъектМетаданныхБизнесПроцесс
//                       - ОбъектМетаданныхДокумент
//                       - ОбъектМетаданныхЗадача
//                       - ОбъектМетаданныхПланВидовРасчета
//                       - ОбъектМетаданныхПланВидовХарактеристик
//                       - ОбъектМетаданныхПланОбмена
//                       - ОбъектМетаданныхПланСчетов
//                       - ОбъектМетаданныхСправочник
//                       - ОбъектМетаданныхТаблица - объект метаданных, для которого формируется список выбора.
//
Процедура ОбработкаПолученияДанныхВыбора(ДанныеВыбора, Знач Параметры, СтандартнаяОбработка, ОбъектМетаданных) Экспорт
	
	Если МультиязычностьПовтИсп.КонфигурацияИспользуетТолькоОдинЯзык(ОбъектМетаданных.ТабличныеЧасти.Найти("Представления") = Неопределено) Тогда
		Возврат;
	КонецЕсли;
	
	СтандартнаяОбработка = Ложь;
	
	ПоляВводаПоСтроке = ОбъектМетаданных.ВводПоСтроке;
	Поля              = Новый Массив;
	
	НаименованияЛокализуемыхРеквизитов = НаименованияЛокализуемыхРеквизитовОбъекта(ОбъектМетаданных);
	Для каждого Поле Из ПоляВводаПоСтроке Цикл
		Если НаименованияЛокализуемыхРеквизитов.Получить(Поле.Имя) = Истина Тогда
			
			Поля.Добавить("Таблица." + Поле.Имя + " ПОДОБНО &СтрокаПоиска СПЕЦСИМВОЛ ""~""");
			
			Если ИспользуетсяПервыйДополнительныйЯзык() Тогда
				Поля.Добавить("Таблица." + Поле.Имя + "Язык1 ПОДОБНО &СтрокаПоиска СПЕЦСИМВОЛ ""~""");
			КонецЕсли;
			
			Если ИспользуетсяВторойДополнительныйЯзык() Тогда
				Поля.Добавить("Таблица." + Поле.Имя + "Язык2 ПОДОБНО &СтрокаПоиска СПЕЦСИМВОЛ ""~""");
			КонецЕсли;

		Иначе
			Поля.Добавить("Таблица." + Поле.Имя + " ПОДОБНО &СтрокаПоиска СПЕЦСИМВОЛ ""~""");
		КонецЕсли;
	КонецЦикла;
	
	ШаблонЗапроса = "ВЫБРАТЬ ПЕРВЫЕ 20
	|	Таблица.Ссылка КАК Ссылка
	|ИЗ
	|	&ИмяОбъекта КАК Таблица
	|ГДЕ
	|	&УсловияОтбора";
	
	ТекстЗапроса = СтрЗаменить(ШаблонЗапроса, "&ИмяОбъекта", ОбъектМетаданных.ПолноеИмя());
	ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&УсловияОтбора", СтрСоединить(Поля, " ИЛИ "));
	
	Запрос = Новый Запрос(ТекстЗапроса);	
	Запрос.УстановитьПараметр("СтрокаПоиска", "%" + ОбщегоНазначения.СформироватьСтрокуДляПоискаВЗапросе(Параметры.СтрокаПоиска) +"%");
	РезультатЗапроса = Запрос.Выполнить().Выбрать();
	
	ДанныеВыбора = Новый СписокЗначений;
	Пока РезультатЗапроса.Следующий() Цикл
		ДанныеВыбора.Добавить(РезультатЗапроса.Ссылка, РезультатЗапроса.Ссылка);
	КонецЦикла;
	
КонецПроцедуры

// Добавляет к имени поля в тексте запроса языковой суффикс текущего языка.
// Примеры конвертации полей:
//   - если параметр ИмяПоля равно "Свойства.Заголовок", то поле преобразует в "Свойства.ЗаголовокЯзык1";
//   - если параметр ИмяПоля равно "Свойства.Заголовок КАК Заголовок", 
//   то поле преобразует в "Свойства.ЗаголовокЯзык1 КАК Заголовок".
// 
// Параметры:
//  ТекстЗапроса - Строка - текст запроса в котором изменяется имя поля
//  ИмяПоля - Строка - имя заменяемого поля
//
Процедура ИзменитьПолеЗапросаПодТекущийЯзык(ТекстЗапроса, ИмяПоля) Экспорт
	
	СуффиксЯзыка = СуффиксТекущегоЯзыка();
	Если ПустаяСтрока(СуффиксЯзыка) Тогда
		Возврат;
	КонецЕсли;
	
	ПозицияПробела = СтрНайти(ИмяПоля, " ");
	НовоеИмяПоля =? (ПозицияПробела > 1,
		Лев(ИмяПоля, ПозицияПробела - 1) + СуффиксЯзыка + Сред(ИмяПоля, ПозицияПробела), ИмяПоля + СуффиксЯзыка);
	
	ТекстЗапроса = СтрЗаменить(ТекстЗапроса, ИмяПоля, НовоеИмяПоля);
	
КонецПроцедуры

#КонецОбласти

#Область СлужебныйПрограммныйИнтерфейс

Функция ТребуетсяУстановкаРегиональныхНастроекИнформационнойБазы() Экспорт
	
	Если (ОбщегоНазначения.РазделениеВключено() И ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных())
		Или ОбщегоНазначения.ЭтоАвтономноеРабочееМесто()  Тогда
		Возврат Ложь;
	КонецЕсли;
	
	УстановитьПривилегированныйРежим(Истина);
	
	Если ДанныеДляИзмененияМультиязычныхРеквизитов() <> Неопределено Тогда
		Возврат Истина;
	КонецЕсли;
	
	Если ЗначениеЗаполнено(Константы.ОсновнойЯзык.Получить()) Тогда
		Возврат Ложь;
	КонецЕсли;
	
	Если ОбновлениеИнформационнойБазыСлужебный.РежимОбновленияДанных() = "НачальноеЗаполнение" 
		И Метаданные.Языки.Количество() > 1 Тогда
		Возврат Истина;
	КонецЕсли;
	
	Константы.ОсновнойЯзык.Установить(ОбщегоНазначения.КодОсновногоЯзыка());
	
	Возврат Ложь;
	
КонецФункции

Функция КодОсновногоЯзыка() Экспорт
	
	УстановитьПривилегированныйРежим(Истина);
	Возврат ПараметрыСеанса.ОсновнойЯзык;
	
КонецФункции

Функция ПредставлениеЯзыка(КодЯзыка) Экспорт
	
	Если ПолучитьДопустимыеКодыЛокализации().Найти(КодЯзыка) = Неопределено Тогда
		Для Каждого Язык Из Метаданные.Языки Цикл
			Если Язык.КодЯзыка = КодЯзыка Тогда
				Возврат Язык.Представление();
			КонецЕсли;
		КонецЦикла;
		Возврат КодЯзыка;
	КонецЕсли;
	
	Представление = ПредставлениеКодаЛокализации(КодЯзыка);
	ЧастиСтроки = СтрРазделить(Представление, " ", Истина);
	ЧастиСтроки[0] = ТРег(ЧастиСтроки[0]);
	Представление = СтрСоединить(ЧастиСтроки, " ");
	
	Возврат Представление;
	
КонецФункции

Функция СведенияОбЯзыках() Экспорт
	Возврат МультиязычностьПовтИсп.СведенияОбЯзыках();
КонецФункции

Функция ОбъектСодержитТЧПредставления(СсылкаИлиПолноеИмяМетаданных, ИмяРеквизита = "") Экспорт
	Возврат МультиязычностьПовтИсп.ОбъектСодержитТЧПредставления(СсылкаИлиПолноеИмяМетаданных, ИмяРеквизита);
КонецФункции

Функция ИмяРеквизитаБезСуффиксаЯзык(Знач ИмяРеквизита) Экспорт
	
	Если ЭтоЛокализуемыйРеквизит(ИмяРеквизита) Тогда
		Возврат Лев(ИмяРеквизита, СтрДлина(ИмяРеквизита) - ДлинаСуффиксаЯзыка());
	КонецЕсли;
	
	Возврат ИмяРеквизита;
	
КонецФункции

Функция ПризнакЛокализуемогоРеквизита() Экспорт
	Возврат "Локализуемый";
КонецФункции

Функция МультиязычныеСтрокиВРеквизитах(ОбъектМетаданных) Экспорт
	
	Возврат МультиязычностьПовтИсп.ЕстьМультиязычныеРеквизитыВШапкеОбъекта(ОбъектМетаданных.ПолноеИмя());
	
КонецФункции

Функция МультиязычныеРеквизитыОбъекта(ОбъектИлиСсылка) Экспорт
	
	ТипОбъекта = ТипЗнч(ОбъектИлиСсылка);
	
	Если ТипОбъекта = Тип("Строка") Или ОбщегоНазначения.ЭтоСсылка(ТипОбъекта) Тогда
		Объект = ОбъектИлиСсылка;
	Иначе
		Объект = ОбъектИлиСсылка.ПолноеИмя();
	КонецЕсли;
	
	Возврат МультиязычностьПовтИсп.МультиязычныеРеквизитыОбъекта(Объект);
	
КонецФункции

Функция ОбновитьМультиязычныеСтрокиПредопределенныхЭлементов(СсылкиНаОбъекты, ОбъектМетаданных) Экспорт
	
	Результат = Новый Структура();
	Результат.Вставить("ПроблемныхОбъектов", 0);
	Результат.Вставить("ОбъектовОбработано", 0);
	
	НастройкиОбновление = НастройкиОбновлениеПредопределенныхДанных(ОбъектМетаданных);
	
	Пока СсылкиНаОбъекты.Следующий() Цикл
		
		Попытка
			
			ОбновитьМультиязычныеСтрокиПредопределенногоЭлемента(СсылкиНаОбъекты.Ссылка, НастройкиОбновление);
			Результат.ОбъектовОбработано = Результат.ОбъектовОбработано + 1;
			
		Исключение
			// Если не удалось обработать элемент, повторяем попытку снова.
			Результат.ПроблемныхОбъектов = Результат.ПроблемныхОбъектов + 1;
			
			ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru = 'Не удалось обработать элемент %1 по причине: 
					|%2'"),
				СсылкиНаОбъекты.Ссылка, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
				
			ЗаписьЖурналаРегистрации(ОбновлениеИнформационнойБазы.СобытиеЖурналаРегистрации(), УровеньЖурналаРегистрации.Предупреждение,
			ОбъектМетаданных, СсылкиНаОбъекты.Ссылка, ТекстСообщения);
			
		КонецПопытки;
		
	КонецЦикла;
	
	Возврат Результат;
	
КонецФункции

Процедура ИзменениеТекстаЗапросаСпискаДляТекущегоЯзыка(Форма, ИмяСписка = "Список") Экспорт
	
	СуффиксЯзыка = СуффиксТекущегоЯзыка();
	
	Если ПустаяСтрока(СуффиксЯзыка) Тогда
		Возврат;
	КонецЕсли;
	
	Список = Форма[ИмяСписка];
	Если ПустаяСтрока(Список.ТекстЗапроса) Тогда
		Возврат;
	КонецЕсли;
	
	ОбъектМетаданных = Неопределено;
	Если ЗначениеЗаполнено(Список.ОсновнаяТаблица) Тогда
		ОбъектМетаданных = ОбщегоНазначения.ОбъектМетаданныхПоПолномуИмени(Список.ОсновнаяТаблица);
	КонецЕсли;
	
	Если ОбъектМетаданных = Неопределено Тогда
		НаборЧастейПутиОбъектаМетаданных = СтрРазделить(Форма.ИмяФормы, ".");
		ИмяОбъектаМетаданных = НаборЧастейПутиОбъектаМетаданных[0] + "." + НаборЧастейПутиОбъектаМетаданных[1];
		ОбъектМетаданных = ОбщегоНазначения.ОбъектМетаданныхПоПолномуИмени(ИмяОбъектаМетаданных);
	КонецЕсли;
	
	Если ОбъектМетаданных = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	ЛокализуемыеРеквизиты = ЛокализуемыеРеквизитыОбъектаДляТекущегоЯзыка(ОбъектМетаданных);
	
	МодельЗапроса = Новый СхемаЗапроса;
	МодельЗапроса.УстановитьТекстЗапроса(Список.ТекстЗапроса);
	
	Для Каждого ПакетЗапроса Из МодельЗапроса.ПакетЗапросов Цикл
		Для Каждого ОператорЗапроса Из ПакетЗапроса.Операторы Цикл
			Для Каждого ИсточникЗапроса Из ОператорЗапроса.Источники Цикл
				Если ТипЗнч(ИсточникЗапроса.Источник) <> Тип("ВложенныйЗапросСхемыЗапроса")
					 И СтрНачинаетсяС(ОбъектМетаданных.ПолноеИмя(), ИсточникЗапроса.Источник.ИмяТаблицы) Тогда
					
					Для каждого ОписаниеРеквизита Из ЛокализуемыеРеквизиты Цикл
						
						ИмяОсновногоРеквизита = Лев(ОписаниеРеквизита.Ключ, СтрДлина(ОписаниеРеквизита.Ключ) - ДлинаСуффиксаЯзыка());
						ПолноеИмя = ИсточникЗапроса.Источник.Псевдоним + "."+ ИмяОсновногоРеквизита;
						
						Для Индекс = 0 По ОператорЗапроса.ВыбираемыеПоля.Количество() - 1 Цикл
							
							ВыбираемоеПолеЗапроса = ОператорЗапроса.ВыбираемыеПоля.Получить(Индекс);
							Если ТипЗнч(ВыбираемоеПолеЗапроса) <> Тип("ВыражениеСхемыЗапроса") Тогда
								Продолжить;
							КонецЕсли;
							
							ВыбираемоеПоле = Строка(ВыбираемоеПолеЗапроса);
							Позиция = СтрНайти(ВыбираемоеПоле, ПолноеИмя);
							
							Если Позиция = 0 Тогда
								Продолжить;
							КонецЕсли;
							
							ТекстВыбораПоля = ИсточникЗапроса.Источник.Псевдоним + "." + ОписаниеРеквизита.Ключ;
							
							Если СтрСравнить(ВыбираемоеПоле, ПолноеИмя) = 0 Тогда
								
								ВыбираемоеПоле = СтрЗаменить(ВыбираемоеПоле, ПолноеИмя, ТекстВыбораПоля);
								
							Иначе
								
								ВыбираемоеПоле = СтрЗаменить(ВыбираемоеПоле, ПолноеИмя + Символы.ПС,
									ТекстВыбораПоля + Символы.ПС);
								ВыбираемоеПоле = СтрЗаменить(ВыбираемоеПоле, ПолноеИмя + " ",
									ТекстВыбораПоля + " " );
								ВыбираемоеПоле = СтрЗаменить(ВыбираемоеПоле, ПолноеИмя + ")",
									ТекстВыбораПоля + ")" );
								
							КонецЕсли;
							
							ОператорЗапроса.ВыбираемыеПоля.Установить(Индекс, Новый ВыражениеСхемыЗапроса(ВыбираемоеПоле));
							
							Если ПакетЗапроса.Колонки.Найти(ИмяОсновногоРеквизита) = Неопределено Тогда
								ПакетЗапроса.Колонки.Получить(Индекс).Псевдоним = ИмяОсновногоРеквизита;
							КонецЕсли;
							
						КонецЦикла;
						
					КонецЦикла;
					
				КонецЕсли;
			КонецЦикла;
		КонецЦикла;
	КонецЦикла;
	
	Список.ТекстЗапроса = МодельЗапроса.ПолучитьТекстЗапроса();
	
КонецПроцедуры

Функция СуффиксТекущегоЯзыка() Экспорт
	
	Возврат СуффиксЯзыка(ТекущийЯзык().КодЯзыка);
	
КонецФункции

// По коду языка возвращает суффикс "Язык1" или "Язык2".
//
Функция СуффиксЯзыка(Язык) Экспорт
	
	Возврат МультиязычностьПовтИсп.СуффиксЯзыка(Язык);
	
КонецФункции

Функция ИспользуетсяПервыйДополнительныйЯзык() Экспорт
	
	Возврат Константы.ИспользоватьДополнительныйЯзык1.Получить() = Истина;
	
КонецФункции

Функция ИспользуетсяВторойДополнительныйЯзык() Экспорт
	
	Возврат Константы.ИспользоватьДополнительныйЯзык2.Получить() = Истина;
	
КонецФункции

// Обновление данных

Процедура ОбработатьОбщиеДанныеДляПереходаНаНовуюВерсию() Экспорт
	
	Если Метаданные.Языки.Количество() = 1 Тогда
		Возврат;
	КонецЕсли;
	
	ОбъектыКОбработке = СписокОбъектовКОбработкеДляПереходаНаНовуюВерсию("Общие");
	
	Если ОбъектыКОбработке.Количество() = 0 Тогда
		Возврат;
	КонецЕсли;
	
	ОбъектовОбработано = 0; 
	ПроблемныхОбъектов = 0;
	
	ОбъектМетаданных    = Неопределено;
	ПараметрыЗаполнения = Неопределено;
	Для каждого ОбъектКОбработке Из ОбъектыКОбработке Цикл
		
		Если ОбъектМетаданных = Неопределено Или ТипЗнч(ОбъектМетаданных) <> ТипЗнч(ОбъектКОбработке) Тогда
			ОбъектМетаданных = Метаданные.НайтиПоТипу(ТипЗнч(ОбъектКОбработке));
			ПараметрыЗаполнения = ОбновлениеИнформационнойБазыСлужебный.НаборПараметровДляЗаполненияОбъекта(ОбъектМетаданных);
		КонецЕсли;
		
		Если ПараметрыЗаполнения <> Неопределено Тогда
			ЗаполнитьИПеренестиСтрокиИзТЧПредставленияВРеквизиты(ОбъектКОбработке, ПараметрыЗаполнения, ОбъектовОбработано, ПроблемныхОбъектов);
		КонецЕсли;
		
	КонецЦикла;
	
	Если ПроблемныхОбъектов > 0 Тогда
		ЗаписьЖурналаРегистрации(ОбновлениеИнформационнойБазы.СобытиеЖурналаРегистрации(), УровеньЖурналаРегистрации.Ошибка,,,
				СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
					НСтр("ru = 'Процедуре %1 не удалось обновить некоторые объекты (пропущены): %2 из %3'"),
					"МультиязычностьСервер.ОбработатьОбщиеДанныеДляПереходаНаНовуюВерсию",
					ПроблемныхОбъектов, ОбъектовОбработано));
	КонецЕсли;	
	
КонецПроцедуры

// Регистрирует объекты к обработке в обработчике обновления
//
Процедура ЗарегистрироватьДанныеКОбработкеДляПереходаНаНовуюВерсию(Параметры) Экспорт
	
	Если Метаданные.Языки.Количество() = 1 Тогда
		Возврат;
	КонецЕсли;
	
	ОбъектыКОбработке = СписокОбъектовКОбработкеДляПереходаНаНовуюВерсию(ВариантДанныхДляОбработкиСУчетомРазделения());

	Если ОбъектыКОбработке.Количество() > 0 Тогда
		ОбновлениеИнформационнойБазы.ОтметитьКОбработке(Параметры, ОбъектыКОбработке);
	КонецЕсли;
	
КонецПроцедуры

Процедура ОбработатьДанныеДляПереходаНаНовуюВерсию(Параметры) Экспорт
	
	ИтогоОбработано    = 0;
	ОбъектовОбработано = 0;
	ПроблемныхОбъектов = 0;
	Порция             = 10000;
	
	ОбрабатываемыеОбъекты = ОбъектыСТЧПредставления(ВариантДанныхДляОбработкиСУчетомРазделения());
	Для Каждого ИмяОбъектСТЧПредставления Из ОбрабатываемыеОбъекты Цикл
		
		Выборка = ОбновлениеИнформационнойБазы.ВыбратьСсылкиДляОбработки(Параметры.Очередь, ИмяОбъектСТЧПредставления);
		
		ПараметрыЗаполнения = Неопределено;
		Если Выборка.Количество() > 0 Тогда
			ПараметрыЗаполнения = ОбновлениеИнформационнойБазыСлужебный.НаборПараметровДляЗаполненияОбъекта(
				ОбщегоНазначения.ОбъектМетаданныхПоПолномуИмени(ИмяОбъектСТЧПредставления));
		КонецЕсли;
		
		Пока Выборка.Следующий() Цикл
			ЗаполнитьИПеренестиСтрокиИзТЧПредставленияВРеквизиты(Выборка.Ссылка, ПараметрыЗаполнения, ОбъектовОбработано, ПроблемныхОбъектов);
		КонецЦикла;
		
		ИтогоОбработано = ИтогоОбработано + ОбъектовОбработано;
		 
		Если ИтогоОбработано >= Порция Тогда
			Прервать;
		КонецЕсли;
	
	КонецЦикла;
	
	Если ОбъектовОбработано = 0 И ПроблемныхОбъектов <> 0 Тогда
		ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Процедуре %1 не удалось обработать некоторые объекты (пропущены): %2'"), 
			"МультиязычностьСервер.ОбработатьДанныеДляПереходаНаНовуюВерсию",
			ПроблемныхОбъектов);
		ВызватьИсключение ТекстСообщения;
	ИначеЕсли ОбъектовОбработано > 0 Тогда
		ЗаписьЖурналаРегистрации(ОбновлениеИнформационнойБазы.СобытиеЖурналаРегистрации(), УровеньЖурналаРегистрации.Информация,,,
			СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru = 'Процедура %1 обработала очередную порцию объектов: %2'"),
				"МультиязычностьСервер.ОбработатьДанныеДляПереходаНаНовуюВерсию",
				ОбъектовОбработано));
	КонецЕсли;
	
	
	ОбъектыСПредопределеннымиЭлементами = ОбновлениеИнформационнойБазыСлужебный.ОбъектыСНачальнымЗаполнением();
	Для каждого ОбъектСПредопределеннымиЭлементами Из ОбъектыСПредопределеннымиЭлементами Цикл
		
		Если ОбрабатываемыеОбъекты.Найти(ОбъектСПредопределеннымиЭлементами.ПолноеИмя()) = Неопределено Тогда
			ОбрабатываемыеОбъекты.Добавить(ОбъектСПредопределеннымиЭлементами.ПолноеИмя());
		КонецЕсли;
		
	КонецЦикла;
	
	Для каждого ОбъектСПредопределеннымиЭлементами Из ОбъектыСПредопределеннымиЭлементами Цикл
		
		Если ИтогоОбработано >= Порция Тогда
			Прервать;
		КонецЕсли;
		
		Выборка = ОбновлениеИнформационнойБазы.ВыбратьСсылкиДляОбработки(Параметры.Очередь, ОбъектСПредопределеннымиЭлементами.ПолноеИмя());
		Если Выборка.Количество() > 0 Тогда
		
			// @skip-check query-in-loop - Порционная обработка данных в обработчике обновления
			ЗаполнитьПустыеМультиязычныеРеквизитыЗначениемОсновногоЯзыка(Выборка, ОбъектСПредопределеннымиЭлементами, ИтогоОбработано);
			
		КонецЕсли;
	КонецЦикла;

	Параметры.ОбработкаЗавершена = ОбновлениеИнформационнойБазы.ОбработкаДанныхЗавершена(Параметры.Очередь, ОбрабатываемыеОбъекты);
	
КонецПроцедуры

////////////////////////////////////////////////////////////////////////////////
// Начальное заполнение элементов данными.

// Параметры:
//  СсылкаНаОбъект - СправочникСсылка
//                 - ПланВидовХарактеристикСсылка
//  НастройкиОбновления - Структура:
//   * ПредопределенныеДанные - ТаблицаЗначений
//   * ОсновнойЯзык - Строка
//   * КодЯзыка2 - Строка
//   * КодЯзыка1 - Строка
//   * ЛокализуемыеРеквизитыОбъекта - см. НастройкиОбновлениеПредопределенныхДанных
// 
Процедура ОбновитьМультиязычныеСтрокиПредопределенногоЭлемента(СсылкаНаОбъект, НастройкиОбновления) Экспорт
	
	ИмяПредопределенныхДанных = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(СсылкаНаОбъект, "ИмяПредопределенныхДанных");
	Если Не ЗначениеЗаполнено(ИмяПредопределенныхДанных) Тогда
		ОбновлениеИнформационнойБазы.ОтметитьВыполнениеОбработки(СсылкаНаОбъект);
		Возврат;
	КонецЕсли;
	
	Элемент = НастройкиОбновления.ПредопределенныеДанные.Найти(ИмяПредопределенныхДанных, "ИмяПредопределенныхДанных");
	
	Если Элемент = Неопределено Тогда
		ОбновлениеИнформационнойБазы.ОтметитьВыполнениеОбработки(СсылкаНаОбъект);
		Возврат;
	КонецЕсли;
	
	НачатьТранзакцию();
	Попытка
		
		Блокировка = Новый БлокировкаДанных;
		ЭлементБлокировки = Блокировка.Добавить(НастройкиОбновления.ИмяОбъектМетаданных);
		ЭлементБлокировки.УстановитьЗначение("Ссылка", СсылкаНаОбъект);
		Блокировка.Заблокировать();
		
		Объект = СсылкаНаОбъект.ПолучитьОбъект();
		Если Объект = Неопределено Тогда // объект может быть уже удален в других сеансах
			ОтменитьТранзакцию();
			Возврат;
		КонецЕсли;
		ЗаблокироватьДанныеДляРедактирования(СсылкаНаОбъект);
		
		Для каждого ЛокализуемыйРеквизитОбъекта Из НастройкиОбновления.ЛокализуемыеРеквизитыОбъекта Цикл
			Имя = ЛокализуемыйРеквизитОбъекта.Ключ;
			Объект[Имя] = Элемент[ИмяЛокализуемогоРеквизита(Имя, НастройкиОбновления.ОсновнойЯзык)];
			
			Если ИспользуетсяПервыйДополнительныйЯзык() И ЗначениеЗаполнено(НастройкиОбновления.КодЯзыка1) Тогда
				Объект[Имя + "Язык1"] = Элемент[ИмяЛокализуемогоРеквизита(Имя, НастройкиОбновления.КодЯзыка1)];
			КонецЕсли;
			Если ИспользуетсяВторойДополнительныйЯзык()  И ЗначениеЗаполнено(НастройкиОбновления.КодЯзыка2) Тогда
				Объект[Имя + "Язык2"] = Элемент[ИмяЛокализуемогоРеквизита(Имя, НастройкиОбновления.КодЯзыка2)];
			КонецЕсли;
			
		КонецЦикла;
		ОбновлениеИнформационнойБазы.ЗаписатьОбъект(Объект);
		ЗафиксироватьТранзакцию();
		
	Исключение
		ОтменитьТранзакцию();
		ВызватьИсключение;
	КонецПопытки;
		
	
КонецПроцедуры

// Параметры:
//  ОбъектМетаданных - ОбъектМетаданных
// 
// Возвращаемое значение:
//  Структура:
//   * ЛокализуемыеРеквизитыОбъекта - Соответствие из КлючИЗначение:
//   ** Ключ - Строка
//   ** Значение - Булево 
//   * КодЯзыка1 - Строка
//   * КодЯзыка2 - Строка
//   * ОсновнойЯзык - Строка
//   * ИмяОбъектМетаданных - Строка
//   * ПредопределенныеДанные - ТаблицаЗначений
//
Функция НастройкиОбновлениеПредопределенныхДанных(ОбъектМетаданных) Экспорт
	
	Результат = Новый Структура;
	Результат.Вставить("ЛокализуемыеРеквизитыОбъекта", Новый Соответствие);
	Результат.Вставить("КодЯзыка1", КодПервогоДополнительногоЯзыкаИнформационнойБазы());
	Результат.Вставить("КодЯзыка2", КодВторогоДополнительногоЯзыкаИнформационнойБазы());
	Результат.Вставить("ОсновнойЯзык", ОбщегоНазначения.КодОсновногоЯзыка());
	Результат.Вставить("ИмяОбъектМетаданных", ОбъектМетаданных.ПолноеИмя());
	Результат.Вставить("ПредопределенныеДанные", Неопределено);
	
	МенеджерОбъекта = ОбщегоНазначения.МенеджерОбъектаПоПолномуИмени(Результат.ИмяОбъектМетаданных);
	
	Результат.ЛокализуемыеРеквизитыОбъекта = НаименованияЛокализуемыхРеквизитовОбъекта(ОбъектМетаданных);
	Результат.ПредопределенныеДанные = ОбновлениеИнформационнойБазыСлужебный.ПредопределенныеДанныеОбъекта(ОбъектМетаданных, МенеджерОбъекта, Результат.ЛокализуемыеРеквизитыОбъекта);
	
	ОбновлениеИнформационнойБазыСлужебный.НастройкиПредопределенныхЭлементов(МенеджерОбъекта, Результат.ПредопределенныеДанные);
	
	Возврат Результат;
	
КонецФункции

Функция МультиязычныеСтрокиРеквизитовИзменены(ПоставляемыеСведения, ДанныеЗапроса, ЛокализуемыеРеквизитыОбъекта, ПараметрыРегистрации) Экспорт
	
	Для каждого ОписаниеРеквизита Из ЛокализуемыеРеквизитыОбъекта Цикл
		
		Если МультиязычныеСтрокиРеквизитаИзменены(ПоставляемыеСведения, ДанныеЗапроса,
				ОписаниеРеквизита.Ключ, ПараметрыРегистрации) Тогда
			Возврат Истина;
		КонецЕсли;
		
	КонецЦикла;
	
	Возврат Ложь;
	
КонецФункции

Функция МультиязычныеСтрокиРеквизитаИзменены(ПоставляемыеСведения, ДанныеЗапроса, ИмяРеквизита, ПараметрыРегистрации) Экспорт
	
	СведенияОбЯзыках = МультиязычностьПовтИсп.СведенияОбЯзыках();
	
	ЗначениеОсновногоЯзыка = ПоставляемыеСведения[ИмяЛокализуемогоРеквизита(ИмяРеквизита, СведенияОбЯзыках.ОсновнойЯзык)];
	Если ПустаяСтрока(ЗначениеОсновногоЯзыка) И ЗначениеЗаполнено(ПоставляемыеСведения[ИмяРеквизита]) Тогда
		ЗначениеОсновногоЯзыка = ПоставляемыеСведения[ИмяРеквизита];
	КонецЕсли;
	
	Если СтрСравнить(ЗначениеОсновногоЯзыка, ДанныеЗапроса[ИмяРеквизита]) <> 0 Тогда
		
		Если ПустаяСтрока(ЗначениеОсновногоЯзыка) Тогда
			Если Не ПараметрыРегистрации.ПропускатьПустые Тогда
				Возврат Истина;
			КонецЕсли;
		Иначе
			Возврат Истина;
		КонецЕсли;
		
	КонецЕсли;
	
	Если ЗначениеЗаполнено(СведенияОбЯзыках.Язык1)
		И СтрСравнить(ПоставляемыеСведения[ИмяЛокализуемогоРеквизита(ИмяРеквизита, СведенияОбЯзыках.Язык1)], ДанныеЗапроса[ИмяРеквизита + "Язык1"]) <> 0  Тогда
		
		Если ПустаяСтрока(ПоставляемыеСведения[ИмяЛокализуемогоРеквизита(ИмяРеквизита, СведенияОбЯзыках.Язык1)]) Тогда
			Если Не ПараметрыРегистрации.ПропускатьПустые Тогда
				Возврат Истина;
			КонецЕсли;
		Иначе
			Возврат Истина;
		КонецЕсли;
		
	КонецЕсли;
	
	Если ЗначениеЗаполнено(СведенияОбЯзыках.Язык2)
		И СтрСравнить(ПоставляемыеСведения[ИмяЛокализуемогоРеквизита(ИмяРеквизита, СведенияОбЯзыках.Язык2)], ДанныеЗапроса[ИмяРеквизита + "Язык2"]) <> 0  Тогда
		
		Если ПустаяСтрока(ПоставляемыеСведения[ИмяЛокализуемогоРеквизита(ИмяРеквизита, СведенияОбЯзыках.Язык2)]) Тогда
			Если Не ПараметрыРегистрации.ПропускатьПустые Тогда
				Возврат Истина;
			КонецЕсли;
		Иначе
			Возврат Истина;
		КонецЕсли;
		
	КонецЕсли;
	
	Возврат Ложь;
	
КонецФункции

// Параметры:
//  ИменаРеквизитовОбъекта - Массив из Строка
//  ЛокализуемыеРеквизитыОбъекта - Соответствие из КлючИЗначение:
//   * Ключ - Строка
//   * Значение - Булево
//
Процедура СформироватьИменаМультиязычныхРеквизитов(Знач ИменаРеквизитовОбъекта, Знач ЛокализуемыеРеквизитыОбъекта) Экспорт
	
	СведенияОбЯзыках = МультиязычностьПовтИсп.СведенияОбЯзыках();
	
	Для каждого РеквизитОбъекта Из ЛокализуемыеРеквизитыОбъекта Цикл
		
		ИменаРеквизитовОбъекта.Добавить(РеквизитОбъекта.Ключ);
		
		Если ЗначениеЗаполнено(СведенияОбЯзыках.Язык1) Тогда
			ИменаРеквизитовОбъекта.Добавить(РеквизитОбъекта.Ключ + "Язык1");
		КонецЕсли;
		Если ЗначениеЗаполнено(СведенияОбЯзыках.Язык2) Тогда
			ИменаРеквизитовОбъекта.Добавить(РеквизитОбъекта.Ключ + "Язык2");
		КонецЕсли;
		
	КонецЦикла;
	
КонецПроцедуры

Процедура ПриПолученииПараметровЗаполненияПредопределенныхДанных(ПараметрыЗаполнения) Экспорт
	
	ПараметрыЗаполнения.Вставить("Языки", СтандартныеПодсистемыСервер.ЯзыкиКонфигурации());
	ПараметрыЗаполнения.Вставить("СведенияОбЯзыках", СведенияОбЯзыках());
	
КонецПроцедуры

Процедура НачальноеЗаполнениеПредопределенныхДанныхЛокализуемыеРеквизиты(ЗаполняемыйЭлемент, ПоддерживаетсяИерархия, СтрокаТаблицы, ПараметрыЗаполнения) Экспорт
	
	СведенияОбЯзыках = СведенияОбЯзыках();
	
	ЛокализуемыеРеквизитыОбъекта = ПараметрыЗаполнения.ЛокализуемыеРеквизитыОбъекта;
	МультиязычныеСтрокиВРеквизитах = ПараметрыЗаполнения.МультиязычныеСтрокиВРеквизитах;
		
	Если ЛокализуемыеРеквизитыОбъекта.Количество() > 0 Тогда
		Если МультиязычныеСтрокиВРеквизитах Тогда
			
			Для каждого ИмяЛокализуемогоРеквизита Из ЛокализуемыеРеквизитыОбъекта Цикл
				
				ЗначениеОсновнойЯзык = СтрокаТаблицы[ИмяЛокализуемогоРеквизита.Ключ + "_" + СведенияОбЯзыках.ОсновнойЯзык];
				Если ПустаяСтрока(ЗначениеОсновнойЯзык) Тогда
					ЗначениеОсновнойЯзык = СтрокаТаблицы[ИмяЛокализуемогоРеквизита.Ключ];
				КонецЕсли;
				ЗаполняемыйЭлемент[ИмяЛокализуемогоРеквизита.Ключ] = ЗначениеОсновнойЯзык;
				
				Если ЗначениеЗаполнено(СведенияОбЯзыках.Язык1) Тогда
					ЗначениеЯзык1 = СтрокаТаблицы[ИмяЛокализуемогоРеквизита.Ключ + "_" + СведенияОбЯзыках.Язык1];
				КонецЕсли;
				Если ПустаяСтрока(ЗначениеЯзык1) Тогда
					ЗначениеЯзык1 = ЗначениеОсновнойЯзык;
				КонецЕсли;
				
				Если ЗначениеЗаполнено(СведенияОбЯзыках.Язык2) Тогда
					ЗначениеЯзык2 = СтрокаТаблицы[ИмяЛокализуемогоРеквизита.Ключ + "_" + СведенияОбЯзыках.Язык2];
				КонецЕсли;
				Если ПустаяСтрока(ЗначениеЯзык2) Тогда
					ЗначениеЯзык2 = ЗначениеОсновнойЯзык;
				КонецЕсли;
				
				ЗаполняемыйЭлемент[ИмяЛокализуемогоРеквизита.Ключ + "Язык1"] = ЗначениеЯзык1;
				ЗаполняемыйЭлемент[ИмяЛокализуемогоРеквизита.Ключ + "Язык2"] = ЗначениеЯзык2;
				
			КонецЦикла;
		КонецЕсли;
		
		Если ПараметрыЗаполнения.ОбъектСодержитТЧПредставления И НЕ (ПоддерживаетсяИерархия И ЗаполняемыйЭлемент.ЭтоГруппа) Тогда
			ОбновлениеИнформационнойБазыСлужебный.НачальноеЗаполнениеТЧПредставления(ЗаполняемыйЭлемент, СтрокаТаблицы, ПараметрыЗаполнения);
		КонецЕсли;
	КонецЕсли;
	
КонецПроцедуры

Процедура ЗаполнитьЭлементыМультиязычнымиНачальнымиДанными(Знач ЗаполняемыйЭлемент, Знач ЛокализуемыеРеквизитыОбъекта, Знач МультиязычныеСтрокиВРеквизитах, Знач ПоддерживаетсяИерархия, Знач СтрокаТаблицы) Экспорт
	
	Если ЛокализуемыеРеквизитыОбъекта.Количество() = 0 Тогда
		Возврат;
	КонецЕсли;
	
	Языки = СтандартныеПодсистемыСервер.ЯзыкиКонфигурации();
	СведенияОбЯзыках = СведенияОбЯзыках();
	
	Если МультиязычныеСтрокиВРеквизитах Тогда
		
		КодЯзыка =СведенияОбЯзыках.ОсновнойЯзык;
		Если ЗначениеЗаполнено(КодЯзыка) Тогда
			Для каждого ИмяЛокализуемогоРеквизита Из ЛокализуемыеРеквизитыОбъекта Цикл
				ЗаполняемыйЭлемент[ИмяЛокализуемогоРеквизита.Ключ] = СтрокаТаблицы[ИмяЛокализуемогоРеквизита.Ключ + "_" + КодЯзыка];
			КонецЦикла;
		КонецЕсли;
		
		КодЯзыка = СведенияОбЯзыках.Язык1;
		Если ЗначениеЗаполнено(КодЯзыка) Тогда
			Для каждого ИмяЛокализуемогоРеквизита Из ЛокализуемыеРеквизитыОбъекта Цикл
				ЗаполняемыйЭлемент[ИмяЛокализуемогоРеквизита.Ключ + "Язык1"] = СтрокаТаблицы[ИмяЛокализуемогоРеквизита.Ключ + "_" + КодЯзыка];
			КонецЦикла;
		КонецЕсли;
		
		КодЯзыка = СведенияОбЯзыках.Язык2;
		Если ЗначениеЗаполнено(КодЯзыка) Тогда
			Для каждого ИмяЛокализуемогоРеквизита Из ЛокализуемыеРеквизитыОбъекта Цикл
				ЗаполняемыйЭлемент[ИмяЛокализуемогоРеквизита.Ключ + "Язык2"] = СтрокаТаблицы[ИмяЛокализуемогоРеквизита.Ключ + "_" + КодЯзыка];
			КонецЦикла;
		КонецЕсли;
		
	ИначеЕсли Не (ПоддерживаетсяИерархия И ЗаполняемыйЭлемент.ЭтоГруппа) Тогда
		
		Для каждого КодЯзыка Из Языки Цикл
			ТаблицаПредставлений = ЗаполняемыйЭлемент.Представления; // ТаблицаЗначений
			НовоеПредставление = ТаблицаПредставлений.Добавить();
			НовоеПредставление.КодЯзыка = КодЯзыка;
			Для каждого ИмяЛокализуемогоРеквизита Из ЛокализуемыеРеквизитыОбъекта Цикл
				Значение = СтрокаТаблицы[ИмяЛокализуемогоРеквизита.Ключ + "_" + КодЯзыка];
				НовоеПредставление[ИмяЛокализуемогоРеквизита.Ключ] = ?(ЗначениеЗаполнено(Значение), Значение, СтрокаТаблицы[ИмяЛокализуемогоРеквизита.Ключ]);
			КонецЦикла;
		КонецЦикла;
		
	КонецЕсли;

КонецПроцедуры

// См. ОбновлениеИнформационнойБазыБСП.ПриДобавленииОбработчиковОбновления.
Процедура ПриДобавленииОбработчиковОбновления(Обработчики) Экспорт
	
	Если Метаданные.Языки.Количество() > 1 Тогда
	
		Обработчик = Обработчики.Добавить();
		Обработчик.Версия = "3.1.6.16";
		Обработчик.Комментарий = НСтр("ru = 'Заполнение значений мультиязычных реквизитов значением основного языка.'");
	
		Если ОбщегоНазначения.РазделениеВключено() 
			 И Не ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных() Тогда
			
			Обработчик.РежимВыполнения = "Оперативно";
			Обработчик.ОбщиеДанные     = Истина;
			Обработчик.Процедура       = "МультиязычностьСервер.ОбработатьОбщиеДанныеДляПереходаНаНовуюВерсию";
		
		Иначе
		
			Обработчик.РежимВыполнения = "Отложенно";
			Обработчик.Процедура = "МультиязычностьСервер.ОбработатьДанныеДляПереходаНаНовуюВерсию";
			
			Обработчик.Идентификатор = Новый УникальныйИдентификатор("68d400bb-e5bb-49da-a567-ebf7458b29f8");
			Обработчик.ПроцедураЗаполненияДанныхОбновления = "МультиязычностьСервер.ЗарегистрироватьДанныеКОбработкеДляПереходаНаНовуюВерсию";
			Обработчик.ПроцедураПроверки = "ОбновлениеИнформационнойБазы.ДанныеОбновленыНаНовуюВерсиюПрограммы";
			
			ОбъектыСТЧПредставления = ОбъектыСТЧПредставления(ВариантДанныхДляОбработкиСУчетомРазделения());
			
			ОбъектыДляОбработки = ОбъектыСНачальнымЗаполнениемСтрокой(ОбъектыСТЧПредставления);
			
			Обработчик.ЧитаемыеОбъекты    = ОбъектыДляОбработки;
			Обработчик.ИзменяемыеОбъекты  = ОбъектыДляОбработки;
			Обработчик.БлокируемыеОбъекты = ОбъектыДляОбработки;
			
		КонецЕсли;

	КонецЕсли;

	
КонецПроцедуры

// Добавляет или изменяет значения реквизитов в объекте.
//
// Параметры:
//  Объект - СправочникОбъект
//         - ДокументОбъект
//         - ПланВидовХарактеристикОбъект
//         - РегистрСведенийЗапись - заполняемый объект.
//  Значения - Структура - где ключ это имя реквизита, а значение содержит строку помещаемую в реквизит.
//  КодЯзыка - Строка - код языка реквизита. Например, "ru".
//
Процедура УстановитьЗначенияРеквизитов(Объект, Значения, Знач КодЯзыка = Неопределено) Экспорт
	
	Если Не ЗначениеЗаполнено(КодЯзыка) Тогда
		КодЯзыка = КодОсновногоЯзыка();
	КонецЕсли;
	
	КодыЯзыков = Новый Массив;
	КодыЯзыков.Добавить(КодЯзыка);
	
	ДоступныеЯзыки = СтандартныеПодсистемыСервер.ЯзыкиКонфигурации();
	Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.Мультиязычность.Печать") Тогда
		МодульУправлениеПечатьюМультиязычность = ОбщегоНазначения.ОбщийМодуль("УправлениеПечатьюМультиязычность");
		ДополнительныеЯзыки = МодульУправлениеПечатьюМультиязычность.ДополнительныеЯзыкиПечатныхФорм();
		ОбщегоНазначенияКлиентСервер.ДополнитьМассив(ДоступныеЯзыки, ДополнительныеЯзыки);
	КонецЕсли;
	
	ОбъектМетаданных = Объект.Метаданные();
	ВсеМультиязычныеРеквизиты = МультиязычныеРеквизитыОбъекта(ОбъектМетаданных);
	НаименованияЛокализуемыхРеквизитовШапки = НаименованияЛокализуемыхРеквизитовОбъектаВШапке(ОбъектМетаданных);
	
	ТЧПредставления = Неопределено;
	Если ОбъектСодержитТЧПредставления(ОбъектМетаданных.ПолноеИмя()) Тогда
		ТЧПредставления = Метаданные.НайтиПоТипу(ТипЗнч(Объект.Представления));
	КонецЕсли;
	
	Для Каждого ЗначениеРеквизита Из Значения Цикл
		ИмяРеквизита = ЗначениеРеквизита.Ключ;
		ЗначенияРеквизита = Новый Соответствие();
		
		СтрокаБезПробелов = СтрЗаменить(ЗначениеРеквизита.Значение, " ", "");
		Если ОбщегоНазначения.СтрокаВВидеНСтр(СтрокаБезПробелов) Тогда
			Для Каждого Язык Из ДоступныеЯзыки Цикл
				Если СтрНайти(СтрокаБезПробелов, Язык +"=") > 0 Тогда
					ЗначенияРеквизита[Язык] = НСтр(ЗначениеРеквизита.Значение, Язык);
				КонецЕсли;
			КонецЦикла;
		Иначе
			ЗначенияРеквизита[КодЯзыка] = ЗначениеРеквизита.Значение;
		КонецЕсли;
		
		Для Каждого Элемент Из ЗначенияРеквизита Цикл
			Язык = Элемент.Ключ;
			Значение = Элемент.Значение;
			
			Если ВсеМультиязычныеРеквизиты[ИмяРеквизита] <> Неопределено Тогда
				
				Если Язык = ОбщегоНазначения.КодОсновногоЯзыка() Тогда
					Объект[ИмяРеквизита] = Значение;
					Продолжить;
				КонецЕсли;
				
				Если НаименованияЛокализуемыхРеквизитовШапки[ИмяРеквизита] <> Неопределено Тогда
					СуффиксЯзыка = СуффиксЯзыка(Язык);
					Если ЗначениеЗаполнено(СуффиксЯзыка) Тогда
						Объект[ИмяРеквизита + СуффиксЯзыка] = Значение;
					КонецЕсли;
				КонецЕсли;
				
				Если ТЧПредставления <> Неопределено 
					 И ТЧПредставления.Реквизиты.Найти(ИмяРеквизита) <> Неопределено Тогда
						
						НайденнаяСтрока = Неопределено;
						Для Каждого СтрокаТаблицы Из Объект.Представления Цикл
							Если СтрокаТаблицы.КодЯзыка = Язык Тогда
								НайденнаяСтрока = СтрокаТаблицы;
								Прервать;
							КонецЕсли;
						КонецЦикла;
						
						Если НайденнаяСтрока =  Неопределено Тогда
							НайденнаяСтрока = Объект.Представления.Добавить();
							НайденнаяСтрока.КодЯзыка = Язык;
						КонецЕсли;
						
						НайденнаяСтрока[ИмяРеквизита] = Значение;
				КонецЕсли;
				
			Иначе // Реквизиту не являющемся мультиязычном устанавливается значение только на основном языке.
				Если КодЯзыка = ОбщегоНазначения.КодОсновногоЯзыка() Тогда
					Объект[ИмяРеквизита] = ЗначенияРеквизита[КодЯзыка];
				КонецЕсли;
			КонецЕсли;
			
		КонецЦикла;
	КонецЦикла;
	
КонецПроцедуры

// Параметры:
//  ИмяПараметра - Строка
//  УстановленныеПараметры - Массив из Строка
//
Процедура УстановкаПараметровСеанса(Знач ИменаПараметровСеанса, УстановленныеПараметры) Экспорт
	
	Если ИменаПараметровСеанса = Неопределено
	 Или ИменаПараметровСеанса.Найти("ОсновнойЯзык") <> Неопределено Тогда
		
		ПараметрыСеанса.ОсновнойЯзык = КодЯзыкаИнформационнойБазы();
		УстановленныеПараметры.Добавить("ОсновнойЯзык");
	КонецЕсли;
	
КонецПроцедуры

Функция КодПервогоДополнительногоЯзыкаИнформационнойБазы() Экспорт
	
	Если Не ИспользуетсяПервыйДополнительныйЯзык() Тогда
		Возврат "";
	КонецЕсли;
	
	КодЯзыка = Константы.ДополнительныйЯзык1.Получить();
	Для Каждого ЯзыкиИзМетаданных Из Метаданные.Языки Цикл
		Если СтрСравнить(ЯзыкиИзМетаданных.КодЯзыка, КодЯзыка) = 0 Тогда
			Возврат КодЯзыка;
		КонецЕсли;
	КонецЦикла;
	
	Возврат "";
	
КонецФункции

Функция КодВторогоДополнительногоЯзыкаИнформационнойБазы() Экспорт
	
	Если Не ИспользуетсяВторойДополнительныйЯзык() Тогда
		Возврат "";
	КонецЕсли;
	
	КодЯзыка = Константы.ДополнительныйЯзык2.Получить();
	Для Каждого ЯзыкиИзМетаданных Из Метаданные.Языки Цикл
		Если СтрСравнить(ЯзыкиИзМетаданных.КодЯзыка, КодЯзыка) = 0 Тогда
			Возврат КодЯзыка;
		КонецЕсли;
	КонецЦикла;
	
	Возврат "";
	
КонецФункции

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

// Параметры:
//  Объект - СправочникОбъект
//         - ДокументОбъект
//         - ДанныеФормыСтруктура:
//            * Ссылка - СправочникСсылка
//                     - ДокументСсылка
//                     - ПланВидовХарактеристикСсылка
//            * ИсходныйКлючЗаписи - РегистрСведенийЗапись
// 
// Возвращаемое значение:
//  ОбъектМетаданныхСправочник
//  ОбъектМетаданныхДокумент
//  ОбъектМетаданных
//
Функция ОбъектМетаданных(Объект) Экспорт
	
	Если ТипЗнч(Объект) = Тип("ДанныеФормыСтруктура") Тогда
		Если Не Объект.Свойство("ИсходныйКлючЗаписи") Тогда
			ТипОбъекта = ТипЗнч(Объект.Ссылка);
		Иначе
			ТипОбъекта = ТипЗнч(Объект.ИсходныйКлючЗаписи);
		КонецЕсли;
	Иначе
		ТипОбъекта = ТипЗнч(Объект);
	КонецЕсли;
	
	ОбъектМетаданные = Метаданные.НайтиПоТипу(ТипОбъекта);
	
	Возврат ОбъектМетаданные;
	
КонецФункции

Функция ИмяЛокализуемогоРеквизита(ИмяРеквизита, КодЯзыка)
	
	Возврат ИмяРеквизита + "_" + КодЯзыка;
	
КонецФункции

// Код основного языка информационной базы
// 
// Возвращаемое значение:
//  Строка - код языка. Например, "ru".
//
Функция КодЯзыкаИнформационнойБазы()
	
	КодОсновногоЯзыка = Константы.ОсновнойЯзык.Получить();
	Если ЗначениеЗаполнено(КодОсновногоЯзыка) Тогда
		Для каждого ЯзыкиКонфигурации Из Метаданные.Языки Цикл
			Если СтрСравнить(ЯзыкиКонфигурации.КодЯзыка, КодОсновногоЯзыка) = 0 Тогда
				Возврат КодОсновногоЯзыка;
			КонецЕсли;
		КонецЦикла;
	КонецЕсли;
	
	Возврат Метаданные.ОсновнойЯзык.КодЯзыка;
	
КонецФункции

// Возвращаемое значение:
//  Структура:
//   * ОсновнойЯзыкСтароеЗначение - Строка
//   * ДополнительныйЯзык1СтароеЗначение - Строка
//   * ДополнительныйЯзык2СтароеЗначение - Строка
//   * ОсновнойЯзыкНовоеЗначение - Строка
//   * ДополнительныйЯзык1НовоеЗначение - Строка
//   * ДополнительныйЯзык2НовоеЗначение - Строка
//
Функция ОписаниеСтарыхИНовыхНастроекЯзыков() Экспорт
	
	ОписаниеКонстант = Новый Структура;
	ОписаниеКонстант.Вставить("ОсновнойЯзыкСтароеЗначение", "");
	ОписаниеКонстант.Вставить("ДополнительныйЯзык1СтароеЗначение", "");
	ОписаниеКонстант.Вставить("ДополнительныйЯзык2СтароеЗначение", "");
	ОписаниеКонстант.Вставить("ОсновнойЯзыкНовоеЗначение", "");
	ОписаниеКонстант.Вставить("ДополнительныйЯзык1НовоеЗначение", "");
	ОписаниеКонстант.Вставить("ДополнительныйЯзык2НовоеЗначение", "");
	
	Возврат ОписаниеКонстант;
	
КонецФункции

Функция ОпределитьТипФормы(ИмяФормы) Экспорт
	
	Результат = "";
	
	ЧастиИмениФормы = СтрРазделить(ВРег(ИмяФормы), ".");
	ОсновнаяФормаСписка = ОсновнаяФормаСписка(ЧастиИмениФормы);
	ОсновнаяФормаВыбора = ОсновнаяФормаДляВыбора(ЧастиИмениФормы);
	
	НайденнаяФорма = Метаданные.НайтиПоПолномуИмени(ИмяФормы);
	
	Если ОсновнаяФормаСписка = НайденнаяФорма  Тогда
		Результат = "ОсновнаяФормаСписка";
	ИначеЕсли ОсновнаяФормаВыбора  = НайденнаяФорма Тогда
		Результат = "ОсновнаяФормаВыбора";
	КонецЕсли;
	
	Возврат Результат;
	
КонецФункции

Функция ЛокализуемыеРеквизитыОбъектаДляТекущегоЯзыка(ОбъектМетаданных, Язык = Неопределено)
	
	СписокРеквизитов = Новый Соответствие;
	
	Если ЗначениеЗаполнено(Язык) Тогда
		ПрефиксЯзыка = Язык;
	Иначе
		ПрефиксЯзыка = СуффиксТекущегоЯзыка();
	КонецЕсли;
	
	СписокРеквизитовОбъекта = Новый Соответствие;
	ОбъектМетаданныхРеквизиты = ОбъектМетаданных.Реквизиты; //  КоллекцияОбъектовМетаданных из ОбъектМетаданныхРеквизит -
	Для Каждого Реквизит Из ОбъектМетаданныхРеквизиты Цикл
		СписокРеквизитовОбъекта.Вставить(Реквизит.Имя, Реквизит);
	КонецЦикла;
	
	ОбъектМетаданныхСтандартныеРеквизиты = ОбъектМетаданных.СтандартныеРеквизиты; // КоллекцияОбъектовМетаданных из ОписаниеСтандартногоРеквизита -
	Для Каждого Реквизит Из ОбъектМетаданныхСтандартныеРеквизиты Цикл
		СписокРеквизитовОбъекта.Вставить(Реквизит.Имя, Реквизит);
	КонецЦикла;
	
	ТекстЗапроса = "ВЫБРАТЬ ПЕРВЫЕ 0
		|	*
		|ИЗ
		|	&ОбъектМетаданныхПолноеИмя КАК ДанныеИсточника";
	
	ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ОбъектМетаданныхПолноеИмя", ОбъектМетаданных.ПолноеИмя());
	Запрос = Новый Запрос(ТекстЗапроса);
	
	РезультатЗапроса = Запрос.Выполнить();
	
	СписокРеквизитов = Новый Соответствие;
	Для каждого Колонка Из РезультатЗапроса.Колонки Цикл
		Если СтрЗаканчиваетсяНа(Колонка.Имя, ПрефиксЯзыка) Тогда
			Реквизит = СписокРеквизитовОбъекта.Получить(Колонка.Имя);
			Если Реквизит = Неопределено Тогда
				Реквизит = Метаданные.ОбщиеРеквизиты.Найти(Колонка.Имя);
			КонецЕсли;
			СписокРеквизитов.Вставить(Колонка.Имя, Реквизит);
			
		КонецЕсли;
	КонецЦикла;
	
	Возврат СписокРеквизитов;
	
КонецФункции

Функция НаименованияЛокализуемыхРеквизитовОбъекта(ОбъектМетаданных, Префикс = "") Экспорт
	
	СписокРеквизитовОбъекта = Новый Соответствие;
	Если МультиязычныеСтрокиВРеквизитах(ОбъектМетаданных) Тогда
		
		ДлинаСуффиксаЯзыка = ДлинаСуффиксаЯзыка();
		
		Запрос = Новый Запрос;
		Запрос.Текст = 
			"ВЫБРАТЬ РАЗРЕШЕННЫЕ ПЕРВЫЕ 0
			|	*
			|ИЗ
			|	&ИмяТаблицы КАК ДанныеИсточника";
		Запрос.Текст = СтрЗаменить(Запрос.Текст, "&ИмяТаблицы", ОбъектМетаданных.ПолноеИмя());
		
		РезультатЗапроса = Запрос.Выполнить();
		
		Для каждого Колонка Из РезультатЗапроса.Колонки Цикл
			Если СтрЗаканчиваетсяНа(Колонка.Имя, "Язык1") Или СтрЗаканчиваетсяНа(Колонка.Имя, "Язык2") Тогда
				СписокРеквизитовОбъекта.Вставить(Префикс + Лев(Колонка.Имя, СтрДлина(Колонка.Имя) - ДлинаСуффиксаЯзыка), Истина);
			КонецЕсли;
		КонецЦикла;
		
	КонецЕсли;
	
	Если ОбъектСодержитТЧПредставления(ОбъектМетаданных.ПолноеИмя()) Тогда
		
		РеквизитыТабличнойЧастиПредставления = ОбъектМетаданных.ТабличныеЧасти.Представления.Реквизиты; // КоллекцияОбъектовМетаданных из ОбъектМетаданныхРеквизит - 
		Для каждого Реквизит Из РеквизитыТабличнойЧастиПредставления Цикл
			Если СтрСравнить(Реквизит.Имя, "КодЯзыка") = 0 Тогда
				Продолжить;
			КонецЕсли;
			СписокРеквизитовОбъекта.Вставить(Префикс + Реквизит.Имя, Истина);
		КонецЦикла;
		
	КонецЕсли;
	
	Возврат СписокРеквизитовОбъекта;
	
КонецФункции

Функция НаименованияЛокализуемыхРеквизитовОбъектаВШапке(ОбъектМетаданных, Префикс = "") Экспорт
	
	СписокРеквизитовОбъекта = Новый Соответствие;
	Если МультиязычныеСтрокиВРеквизитах(ОбъектМетаданных) Тогда
	
		ДлинаСуффиксаЯзыка = ДлинаСуффиксаЯзыка();
		
		Запрос = Новый Запрос;
		Запрос.Текст = 
			"ВЫБРАТЬ РАЗРЕШЕННЫЕ ПЕРВЫЕ 0
			|	*
			|ИЗ
			|	&ИмяТаблицы КАК ДанныеИсточника";
		Запрос.Текст = СтрЗаменить(Запрос.Текст, "&ИмяТаблицы", ОбъектМетаданных.ПолноеИмя());
		
		РезультатЗапроса = Запрос.Выполнить();
		
		Для каждого Колонка Из РезультатЗапроса.Колонки Цикл
			Если СтрЗаканчиваетсяНа(Колонка.Имя, "Язык1") Или СтрЗаканчиваетсяНа(Колонка.Имя, "Язык2") Тогда
				СписокРеквизитовОбъекта.Вставить(Префикс + Лев(Колонка.Имя, СтрДлина(Колонка.Имя) - ДлинаСуффиксаЯзыка), Истина);
			КонецЕсли;
		КонецЦикла;
	КонецЕсли;
	
	Возврат СписокРеквизитовОбъекта;
	
КонецФункции

Функция ДлинаСуффиксаЯзыка()
	
	Возврат СтрДлина("Язык1");
	
КонецФункции

Функция ОсновнаяФормаСписка(ЧастиИмениФормы)
	
	Если ЧастиИмениФормы[0]= "СПРАВОЧНИК"
		Или ЧастиИмениФормы[0] = "ДОКУМЕНТ"
		Или ЧастиИмениФормы[0] = "ПЕРЕЧИСЛЕНИЕ"
		Или ЧастиИмениФормы[0] = "ПЛАНВИДОВХАРАКТЕРИСТИК"
		Или ЧастиИмениФормы[0] = "ПЛАНСЧЕТОВ"
		Или ЧастиИмениФормы[0] = "ПЛАНВИДОВРАСЧЕТА"
		Или ЧастиИмениФормы[0] = "БИЗНЕСПРОЦЕСС"
		Или ЧастиИмениФормы[0] = "ЗАДАЧА"
		Или ЧастиИмениФормы[0] = "ЗАДАЧА"
		Или ЧастиИмениФормы[0] = "РЕГИСТРБУХГАЛТЕРИИ"
		Или ЧастиИмениФормы[0] = "РЕГИСТРНАКОПЛЕНИЯ"
		Или ЧастиИмениФормы[0] = "РЕГИСТРРАСЧЕТА"
		Или ЧастиИмениФормы[0] = "РЕГИСТРСВЕДЕНИЙ"
		Или ЧастиИмениФормы[0] = "ПЛАНОБМЕНА" Тогда
			Возврат ОбщегоНазначения.ОбъектМетаданныхПоПолномуИмени(ЧастиИмениФормы[0] + "." + ЧастиИмениФормы[1]).ОсновнаяФормаСписка;
	КонецЕсли;
	
	Возврат Неопределено;
	
КонецФункции

Функция ОсновнаяФормаДляВыбора(ЧастиИмениФормы)
	
	Если ЧастиИмениФормы[0]= "СПРАВОЧНИК"
		Или ЧастиИмениФормы[0] = "ДОКУМЕНТ"
		Или ЧастиИмениФормы[0] = "ПЕРЕЧИСЛЕНИЕ"
		Или ЧастиИмениФормы[0] = "ПЛАНВИДОВХАРАКТЕРИСТИК"
		Или ЧастиИмениФормы[0] = "ПЛАНСЧЕТОВ"
		Или ЧастиИмениФормы[0] = "БИЗНЕСПРОЦЕСС"
		Или ЧастиИмениФормы[0] = "ЗАДАЧА"
		Или ЧастиИмениФормы[0] = "ЗАДАЧА"
		Или ЧастиИмениФормы[0] = "ПЛАНОБМЕНА" Тогда
			Возврат ОбщегоНазначения.ОбъектМетаданныхПоПолномуИмени(ЧастиИмениФормы[0] + "." + ЧастиИмениФормы[1]).ОсновнаяФормаДляВыбора;
	КонецЕсли;
	
	Возврат Неопределено;
	
КонецФункции

Функция ИменаОбъектовСМультиязычнымиРеквизитами() Экспорт
	
	МультиязычныеОбъекты = Новый Соответствие;
	
	Для каждого Элемент Из Метаданные.ФункциональныеОпции["ИспользоватьДополнительныйЯзык1"].Состав Цикл
		
		Реквизит = Элемент.Объект;
		ИмяРеквизита = Лев(Реквизит.Имя, СтрДлина(Реквизит.Имя) - СтрДлина(СуффиксПервогоЯзыка()));
		
		Если Метаданные.ОбщиеРеквизиты.Содержит(Реквизит) Тогда
			АвтоИспользование = (Реквизит.АвтоИспользование = Метаданные.СвойстваОбъектов.АвтоИспользованиеОбщегоРеквизита.Использовать);
			Для каждого ЭлементСостава Из Реквизит.Состав Цикл
				
				Если ЭлементСостава.Использование = Метаданные.СвойстваОбъектов.ИспользованиеОбщегоРеквизита.Использовать
					ИЛИ (АвтоИспользование И ЭлементСостава.Использование = Метаданные.СвойстваОбъектов.ИспользованиеОбщегоРеквизита.Авто) Тогда
					
					Если МультиязычныеОбъекты[ЭлементСостава.Метаданные.ПолноеИмя()] = Неопределено Тогда
						СписокРеквизитов = Новый Массив;
						СписокРеквизитов.Добавить(ИмяРеквизита);
						МультиязычныеОбъекты.Вставить(ЭлементСостава.Метаданные.ПолноеИмя(), СписокРеквизитов);
					Иначе
						СписокРеквизитов = МультиязычныеОбъекты[ЭлементСостава.Метаданные.ПолноеИмя()]; // Массив
						СписокРеквизитов.Добавить(ИмяРеквизита);
					КонецЕсли;
					
				КонецЕсли;
				
			КонецЦикла;
		Иначе
			ОбъектМетаданных = Реквизит.Родитель();
			Если ОбъектМетаданных <> Неопределено Тогда
				
				Если МультиязычныеОбъекты[ОбъектМетаданных.ПолноеИмя()] = Неопределено Тогда
					СписокРеквизитов = Новый Массив;
					СписокРеквизитов.Добавить(ИмяРеквизита);
					МультиязычныеОбъекты.Вставить(ОбъектМетаданных.ПолноеИмя(), СписокРеквизитов);
				Иначе
					СписокРеквизитов = МультиязычныеОбъекты[ОбъектМетаданных.ПолноеИмя()]; // Массив
					СписокРеквизитов.Добавить(ИмяРеквизита);
				КонецЕсли;
				
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;
	
	Возврат МультиязычныеОбъекты;
	
КонецФункции

Процедура ОчиститьМультиязычныеРеквизиты(Объект, ОбъектМетаданные)
	
	Если МультиязычныеСтрокиВРеквизитах(ОбъектМетаданные) Тогда
		
		СписокМультиязычныхРеквизитов = НаименованияЛокализуемыхРеквизитовОбъектаВШапке(ОбъектМетаданные);
		Для Каждого Реквизит Из СписокМультиязычныхРеквизитов Цикл
			Объект[Реквизит.Ключ + "Язык1"] = "";
			Объект[Реквизит.Ключ + "Язык2"] = "";
		КонецЦикла;
		
	ИначеЕсли Объект.Свойство("Представления") Тогда
		
		Объект.Представления.Очистить();
		
	КонецЕсли;
	
КонецПроцедуры

Функция ЭтоОсновнойЯзык() Экспорт
	
	Возврат СтрСравнить(ОбщегоНазначения.КодОсновногоЯзыка(), ТекущийЯзык().КодЯзыка) = 0;
	
КонецФункции

Процедура ЗаполнитьПустыеМультиязычныеРеквизитыЗначениемОсновногоЯзыка(Выборка, ОбъектМетаданных, ИтогоОбработано)
	
	ОбъектовОбработано = 0;
	ПроблемныхОбъектов = 0;
	
	Пока Выборка.Следующий() Цикл
		
		ИтогоОбработано = ИтогоОбработано + 1;
		
		Блокировка = Новый БлокировкаДанных;
		ЭлементБлокировки = Блокировка.Добавить(ОбъектМетаданных.ПолноеИмя());
		ЭлементБлокировки.УстановитьЗначение("Ссылка", Выборка.Ссылка);
		
		НачатьТранзакцию();
		Попытка
			
			Блокировка.Заблокировать();
			
			ТекущийОбъект = Выборка.Ссылка.ПолучитьОбъект();
			Если ТекущийОбъект <> Неопределено Тогда
				
				ЗаблокироватьДанныеДляРедактирования(Выборка.Ссылка);
				
				// @skip-check query-in-loop - Порционная обработка больших объемов данных.
				ИменаЛокализуемыхРеквизитов = НаименованияЛокализуемыхРеквизитовОбъектаВШапке(ОбъектМетаданных);
				
				Для Каждого Реквизит Из ИменаЛокализуемыхРеквизитов Цикл
					
					ЗначениеРеквизита = ТекущийОбъект[Реквизит.Ключ];
					Если ПустаяСтрока(ЗначениеРеквизита) Тогда
						Продолжить;
					КонецЕсли;
					
					Если ПустаяСтрока(ТекущийОбъект[Реквизит.Ключ + "Язык1"]) Тогда
						ТекущийОбъект[Реквизит.Ключ + "Язык1"] = ЗначениеРеквизита;
					КонецЕсли;
					
					Если ПустаяСтрока(ТекущийОбъект[Реквизит.Ключ + "Язык2"]) Тогда
						ТекущийОбъект[Реквизит.Ключ + "Язык2"] = ЗначениеРеквизита;
					КонецЕсли;
				КонецЦикла;
				
				ОбновлениеИнформационнойБазы.ЗаписатьОбъект(ТекущийОбъект);
				
			Иначе
				ОбновлениеИнформационнойБазы.ОтметитьВыполнениеОбработки(Выборка.Ссылка);
			КонецЕсли;
			
			ОбъектовОбработано = ОбъектовОбработано + 1;
			ЗафиксироватьТранзакцию();
		Исключение
			
			ОтменитьТранзакцию();
			// Если не удалось обработать какой-либо объект, повторяем попытку снова.
			ПроблемныхОбъектов = ПроблемныхОбъектов + 1;
			
			ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru = 'Не удалось заполнить мультиязычные реквизиты объекта %1 по причине:
				|%2'"), Выборка.Ссылка, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
			
			ЗаписьЖурналаРегистрации(ОбновлениеИнформационнойБазы.СобытиеЖурналаРегистрации(), УровеньЖурналаРегистрации.Предупреждение,
				ОбъектМетаданных, Выборка.Ссылка, ТекстСообщения);
			
		КонецПопытки;
		
	КонецЦикла;
		
	Если ОбъектовОбработано = 0 И ПроблемныхОбъектов <> 0 Тогда
		ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Не удалось заполнить мультиязычные реквизиты в некоторых объектах (пропущены): %1'"), 
			ПроблемныхОбъектов);
		ВызватьИсключение ТекстСообщения;
	Иначе
		ЗаписьЖурналаРегистрации(ОбновлениеИнформационнойБазы.СобытиеЖурналаРегистрации(), УровеньЖурналаРегистрации.Информация,
			ОбъектМетаданных,,
			СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru = 'Заполнены мультиязычные реквизиты в очередной порции объектов: %1'"),
				ОбъектовОбработано));
	КонецЕсли;
	
КонецПроцедуры

// Параметры:
//  Реквизит - ОбъектМетаданныхРеквизит
//           - ОписаниеСтандартногоРеквизита
//
Функция ЭтоЛокализуемыйРеквизит(ИмяРеквизита)
	Возврат СтрЗаканчиваетсяНа(ИмяРеквизита, "Язык1") Или СтрЗаканчиваетсяНа(ИмяРеквизита, "Язык2");
КонецФункции

// Параметры:
//  ВариантДанных - Строка - Варианты: Общие, Разделенные, Все 
// 
// Возвращаемое значение:
//  Массив - объекты СТЧПредставления
//
Функция ОбъектыСТЧПредставления(ВариантДанных)
	
	ОбъектыСТЧПредставления = Новый Массив;

	Если ВариантДанных = "Разделенные" Или ВариантДанных = "Все" Тогда
			
		Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.КонтактнаяИнформация") Тогда
			МодульУправлениеКонтактнойИнформациейСлужебный = ОбщегоНазначения.ОбщийМодуль("УправлениеКонтактнойИнформациейСлужебный");
			МодульУправлениеКонтактнойИнформациейСлужебный.ПриОпределенииОбъектовСТабличнойЧастьюПредставление(ОбъектыСТЧПредставления);
		КонецЕсли;
		
		Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ВариантыОтчетов") Тогда
			МодульВариантыОтчетовСлужебный = ОбщегоНазначения.ОбщийМодуль("ВариантыОтчетовСлужебный");
			МодульВариантыОтчетовСлужебный.ПриОпределенииОбъектовСТабличнойЧастьюПредставление(ОбъектыСТЧПредставления);
		КонецЕсли;
		
		Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.Свойства") Тогда
			МодульУправлениеСвойствамиСлужебный = ОбщегоНазначения.ОбщийМодуль("УправлениеСвойствамиСлужебный");
			МодульУправлениеСвойствамиСлужебный.ПриОпределенииОбъектовСТабличнойЧастьюПредставление(ОбъектыСТЧПредставления);
		КонецЕсли;
	КонецЕсли;
	
	Если ВариантДанных = "Общие" Или ВариантДанных = "Все" Тогда
		Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ВариантыОтчетов") Тогда
			МодульВариантыОтчетовСлужебный = ОбщегоНазначения.ОбщийМодуль("ВариантыОтчетовСлужебный");
			МодульВариантыОтчетовСлужебный.ПриОпределенииОбъектовСТабличнойЧастьюПредставлениеОбщиеДанные(ОбъектыСТЧПредставления);
		КонецЕсли;
	КонецЕсли;
	
	Возврат ОбъектыСТЧПредставления;
	
КонецФункции

Функция ВариантДанныхДляОбработкиСУчетомРазделения()
	Возврат ?(ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных(), "Разделенные", "Все");
КонецФункции

Процедура ЗаполнитьИПеренестиСтрокиИзТЧПредставленияВРеквизиты(Ссылка, ПараметрыЗаполнения, ОбъектовОбработано, ПроблемныхОбъектов)
	
	ОбъектМетаданных = Ссылка.Метаданные(); // ОбъектМетаданных
	
	ТабличнаяЧастьОбъекта = ОбъектМетаданных.ТабличныеЧасти.Найти("Представления"); // ОбъектМетаданныхТабличнаяЧасть
	Если ТабличнаяЧастьОбъекта = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	Иерархический = (ОбщегоНазначения.ЭтоСправочник(ОбъектМетаданных)
		ИЛИ ОбщегоНазначения.ЭтоПланВидовХарактеристик(ОбъектМетаданных))
		И ОбъектМетаданных.Иерархический;
		
	Если Иерархический И ОбъектМетаданных.ВидИерархии
		= Метаданные.СвойстваОбъектов.ВидИерархии.ИерархияГруппИЭлементов Тогда
		
		ТабличнаяЧастьОбъекта = ОбъектМетаданных.ТабличныеЧасти.Найти("Представления"); // ОбъектМетаданныхТабличнаяЧасть
		ЭтоГруппа = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Ссылка, "ЭтоГруппа");

		Если ТабличнаяЧастьОбъекта.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляЭлемента
			 И ЭтоГруппа Тогда
				Возврат;
		ИначеЕсли ТабличнаяЧастьОбъекта.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппы
			 И Не ЭтоГруппа Тогда
				Возврат;
		КонецЕсли;
	КонецЕсли;
	
	Блокировка = Новый БлокировкаДанных;
	ЭлементБлокировки = Блокировка.Добавить(ОбъектМетаданных.ПолноеИмя());
	ЭлементБлокировки.УстановитьЗначение("Ссылка", Ссылка);
	
	Языки = СтандартныеПодсистемыСервер.ЯзыкиКонфигурации();
	
	НачатьТранзакцию();
	Попытка
		
		Блокировка.Заблокировать();
		ЗаблокироватьДанныеДляРедактирования(Ссылка);
		
		Объект = Ссылка.ПолучитьОбъект();
		
		Для Каждого КодЯзыка Из Языки Цикл
			
			Если СтрСравнить(ОбщегоНазначения.КодОсновногоЯзыка(), КодЯзыка) = 0 Тогда
				Продолжить;
			КонецЕсли;
			
			Отбор = Новый Структура("КодЯзыка", КодЯзыка);
			НайденныеСтроки = Объект.Представления.НайтиСтроки(Отбор);
			
			Если НайденныеСтроки.Количество() > 0 Тогда
				СтрокаТаблицы = НайденныеСтроки[0];
			Иначе
				СтрокаТаблицы = Объект.Представления.Добавить();
				СтрокаТаблицы.КодЯзыка = КодЯзыка;
			КонецЕсли;
			
			Для каждого КолонкаРеквизита Из ТабличнаяЧастьОбъекта.Реквизиты Цикл
				
				ИмяРеквизита = КолонкаРеквизита.Имя;
				Если ИмяРеквизита = "КодЯзыка" Тогда
					Продолжить;
				КонецЕсли;
				
				ЗначениеНаОсновномЯзыке = Объект[ИмяРеквизита];
				
				Если ПустаяСтрока(СтрокаТаблицы[ИмяРеквизита]) Тогда
					
					ДанныеЗаполнения = НачальноеЗначениеРеквизита(ПараметрыЗаполнения, ИмяРеквизита, Объект, КодЯзыка);
					Если ПустаяСтрока(ДанныеЗаполнения) Тогда
						ДанныеЗаполнения = ЗначениеНаОсновномЯзыке;
					КонецЕсли;
				
					Если ЗначениеЗаполнено(ДанныеЗаполнения) Тогда
						
						Если СтрСравнить(ОбщегоНазначения.КодОсновногоЯзыка(), КодЯзыка) = 0 Тогда
							Объект[ИмяРеквизита] = ДанныеЗаполнения;
						ИначеЕсли СтрСравнить(КодПервогоДополнительногоЯзыкаИнформационнойБазы(), КодЯзыка) = 0 Тогда
							Объект[ИмяРеквизита + СуффиксПервогоЯзыка()] = ДанныеЗаполнения;
						ИначеЕсли СтрСравнить(КодВторогоДополнительногоЯзыкаИнформационнойБазы(), КодЯзыка) = 0 Тогда
							Объект[ИмяРеквизита + СуффиксВторогоЯзыка()] = ДанныеЗаполнения;
						КонецЕсли;
						
					КонецЕсли;
				Иначе
					
					Если СтрСравнить(КодПервогоДополнительногоЯзыкаИнформационнойБазы(), КодЯзыка) = 0 
						И ПустаяСтрока(Объект[ИмяРеквизита + СуффиксПервогоЯзыка()]) Тогда
							Объект[ИмяРеквизита + СуффиксПервогоЯзыка()] = СтрокаТаблицы[ИмяРеквизита];
					ИначеЕсли СтрСравнить(КодВторогоДополнительногоЯзыкаИнформационнойБазы(), КодЯзыка) = 0
							И ПустаяСтрока(Объект[ИмяРеквизита + СуффиксВторогоЯзыка()])Тогда
						Объект[ИмяРеквизита + СуффиксВторогоЯзыка()] = СтрокаТаблицы[ИмяРеквизита];
					КонецЕсли;
					
				КонецЕсли;
				
			КонецЦикла;
			
		КонецЦикла;
		
		ОбновлениеИнформационнойБазы.ЗаписатьОбъект(Объект);
		ОбъектовОбработано = ОбъектовОбработано + 1;
		ЗафиксироватьТранзакцию();
		
	Исключение
		ОтменитьТранзакцию();
		
		ПроблемныхОбъектов = ПроблемныхОбъектов + 1;
		
		ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Не удалось обработать объект: %1 по причине: %2'"),
				Ссылка, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
		ЗаписьЖурналаРегистрации(ОбновлениеИнформационнойБазы.СобытиеЖурналаРегистрации(), УровеньЖурналаРегистрации.Предупреждение,
			Ссылка.Метаданные(), Ссылка, ТекстСообщения);
	КонецПопытки;
	
КонецПроцедуры

// Параметры:
//  СписокОбъектов - Массив
// 
// Возвращаемое значение:
//  Строка - список полных имен объектов через запятую
//
Функция ОбъектыСНачальнымЗаполнениемСтрокой(СписокОбъектов)
	
	ОбъектыСНачальнымЗаполнением = ОбъектыСНачальнымЗаполнением(ВариантДанныхДляОбработкиСУчетомРазделения());

	Для каждого ОбъектСПредопределеннымиЭлементами Из ОбъектыСНачальнымЗаполнением Цикл
		ПолноеИмя = ОбъектСПредопределеннымиЭлементами.ПолноеИмя();
		Если СписокОбъектов.Найти(ПолноеИмя) = Неопределено Тогда
			СписокОбъектов.Добавить(ПолноеИмя);
		КонецЕсли;
	КонецЦикла;
	
	Возврат СтрСоединить(СписокОбъектов, ",");
	
КонецФункции

Функция СписокОбъектовКОбработкеДляПереходаНаНовуюВерсию(ВариантДанных)
	
	ОбъектыКОбработке = Новый Массив();
	РазделительЗапросов = Символы.ПС + " ОБЪЕДИНИТЬ ВСЕ " + Символы.ПС;
	
	СведенияОбЯзыках = МультиязычностьПовтИсп.СведенияОбЯзыках();
	Если ЗначениеЗаполнено(СведенияОбЯзыках.Язык1) Или ЗначениеЗаполнено(СведенияОбЯзыках.Язык2) Тогда
	
		ОбъектыСПредопределеннымиЭлементами = ОбъектыСНачальнымЗаполнением(ВариантДанных);
		
		ШаблонЗапроса = "ВЫБРАТЬ
			|	ДанныеОбъекта.Ссылка
			|ИЗ
			|	&Таблица КАК ДанныеОбъекта
			|ГДЕ
			|	&УсловиеОтбора";
		
		НаборЗапросов = Новый Массив;
		
		Для каждого ОбъектМетаданныхСЭлементами Из ОбъектыСПредопределеннымиЭлементами Цикл
			
			// @skip-check query-in-loop - Порционная обработка больших объемов данных.
			ЛокализуемыеРеквизитыОбъекта = НаименованияЛокализуемыхРеквизитовОбъектаВШапке(ОбъектМетаданныхСЭлементами);
			Отборы = Новый Массив;
			
			Для каждого РеквизитОбъекта Из ЛокализуемыеРеквизитыОбъекта Цикл
				
				Если Не РеквизитОбъекта.Значение Тогда
					Продолжить;
				КонецЕсли;
				
				Если ЗначениеЗаполнено(СведенияОбЯзыках.Язык1) И ЗначениеЗаполнено(СведенияОбЯзыках.Язык2) Тогда
					ШаблонОтбора = "ВЫРАЗИТЬ(&Реквизит КАК СТРОКА(1)) <> """"
					| И (ВЫРАЗИТЬ(&Язык1 КАК СТРОКА(1)) = """" ИЛИ ВЫРАЗИТЬ(&Язык2 КАК СТРОКА(1)) = """")";
					
					ШаблонОтбора = СтрЗаменить(ШаблонОтбора, "&Язык1", РеквизитОбъекта.Ключ + "Язык1");
					ШаблонОтбора = СтрЗаменить(ШаблонОтбора, "&Язык2", РеквизитОбъекта.Ключ + "Язык2");
					
				Иначе
					ШаблонОтбора = "ВЫРАЗИТЬ(&Реквизит КАК СТРОКА(1)) <> """"
					| И ВЫРАЗИТЬ(&Язык1Или2 КАК СТРОКА(1)) = """"";
					
					Если ЗначениеЗаполнено(СведенияОбЯзыках.Язык2) Тогда
						ШаблонОтбора = СтрЗаменить(ШаблонОтбора, "&Язык1Или2", РеквизитОбъекта.Ключ + "Язык2");
					Иначе
						ШаблонОтбора = СтрЗаменить(ШаблонОтбора, "&Язык1Или2", РеквизитОбъекта.Ключ + "Язык1");
					КонецЕсли;
					
				КонецЕсли;
				
				ТекстОтбора = СтрЗаменить(ШаблонОтбора, "&Реквизит", РеквизитОбъекта.Ключ);
				Отборы.Добавить(ТекстОтбора);
				
			КонецЦикла;
			
			Если Отборы.Количество() = 0 Тогда
				Продолжить;
			КонецЕсли;
				
			ТекстЗапросаПредварительный = СтрЗаменить(ШаблонЗапроса, "&Таблица", ОбъектМетаданныхСЭлементами.ПолноеИмя());
			ТекстЗапросаПредварительный = СтрЗаменить(ТекстЗапросаПредварительный, "&УсловиеОтбора", СтрСоединить(Отборы, " ИЛИ "));
			НаборЗапросов.Добавить(ТекстЗапросаПредварительный);
			
		КонецЦикла;
		
		Если НаборЗапросов.Количество() > 0 Тогда
			
			Запрос = Новый Запрос;
			Запрос.Текст = СтрСоединить(НаборЗапросов, РазделительЗапросов);
			РезультатыЗапроса = Запрос.Выполнить().Выгрузить();
			ОбъектыКОбработке = РезультатыЗапроса.ВыгрузитьКолонку("Ссылка");
			
		КонецЕсли;
		
	КонецЕсли;
	
	// Отдельная порция объектов для регистрации с табличной частью Представления
	ОбъектыСТЧПредставления = ОбъектыСТЧПредставления(ВариантДанных);
	
	Если ОбъектыСТЧПредставления.Количество() > 0 Тогда
		
		ШаблонЗапроса = "ВЫБРАТЬ
		|СправочникСТЧПредставления.Ссылка
		|ИЗ
		|	#ТаблицаПредставления КАК СправочникСТЧПредставления
		|	ЛЕВОЕ СОЕДИНЕНИЕ #Таблица КАК СправочникСТЧ
		|		ПО СправочникСТЧПредставления.Ссылка = СправочникСТЧ.Ссылка
		|ГДЕ СправочникСТЧПредставления.КодЯзыка = ""&КодЯзыка"" И &Условие";
		
		ШаблонГде = "(ВЫРАЗИТЬ(СправочникСТЧПредставления.%1 КАК СТРОКА(10)) <> """" 
		|И ВЫРАЗИТЬ(СправочникСТЧ.%1#СуффиксЯзыка КАК СТРОКА(10)) = """")";
		
		НаборЗапросов = Новый Массив;
		
		Для Каждого ИмяОбъектаМетаданных Из ОбъектыСТЧПредставления Цикл
			
			ОбъектМетаданных = Метаданные.НайтиПоПолномуИмени(ИмяОбъектаМетаданных);
			ТабличнаяЧастьОбъекта = ОбъектМетаданных.ТабличныеЧасти.Найти("Представления"); // ОбъектМетаданныхТабличнаяЧасть
			
			УсловияОтбора = Новый Массив;
			Для Каждого МультиязычныйРеквизит Из ТабличнаяЧастьОбъекта.Реквизиты Цикл
				Если МультиязычныйРеквизит.Имя = "КодЯзыка" Тогда
					Продолжить;
				КонецЕсли;
				
				УсловияОтбора.Добавить(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
					ШаблонГде, МультиязычныйРеквизит.Имя));
			КонецЦикла;
			
			ТекстЗапросаГде = "(" + СтрСоединить(УсловияОтбора, " ИЛИ ") + ")";
			
			Если ОбъектМетаданных.Иерархический 
				И ОбъектМетаданных.ВидИерархии = Метаданные.СвойстваОбъектов.ВидИерархии.ИерархияГруппИЭлементов Тогда
				
				Если ТабличнаяЧастьОбъекта.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляЭлемента Тогда
					ТекстЗапросаГде = ТекстЗапросаГде + "
					|И СправочникСТЧ.ЭтоГруппа <> ИСТИНА";
				ИначеЕсли ТабличнаяЧастьОбъекта.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппы Тогда
					ТекстЗапросаГде = ТекстЗапросаГде + "
					|И СправочникСТЧ.ЭтоГруппа = ИСТИНА";
				КонецЕсли;
			КонецЕсли;
			
			ТекстЗапроса = СтрЗаменить(ШаблонЗапроса, "#ТаблицаПредставления", 
				ОбъектМетаданных.ПолноеИмя() + "." + "Представления");
			ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "#Таблица", ОбъектМетаданных.ПолноеИмя());
			
			ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&Условие", ТекстЗапросаГде);
			НаборЗапросов.Добавить(ТекстЗапроса);
			
		КонецЦикла;
		
		ТекстЗапроса = СтрСоединить(НаборЗапросов, РазделительЗапросов);
		Запрос = Новый Запрос;
		
		Если ИспользуетсяПервыйДополнительныйЯзык() Тогда
			Запрос.Текст = СтрЗаменить(ТекстЗапроса, "#СуффиксЯзыка", СуффиксПервогоЯзыка());
			Запрос.Текст = СтрЗаменить(Запрос.Текст, "&КодЯзыка", КодПервогоДополнительногоЯзыкаИнформационнойБазы());
		КонецЕсли;
		
		Если ИспользуетсяВторойДополнительныйЯзык() Тогда 
			
			Если ЗначениеЗаполнено(Запрос.Текст) Тогда
				Запрос.Текст = Запрос.Текст + ОбщегоНазначения.РазделительПакетаЗапросов();
			КонецЕсли;
			
			ЗапросТекст = СтрЗаменить(ТекстЗапроса, "#СуффиксЯзыка", СуффиксВторогоЯзыка());
			Запрос.Текст = Запрос.Текст + СтрЗаменить(ЗапросТекст, "&КодЯзыка", 
				КодВторогоДополнительногоЯзыкаИнформационнойБазы());
			
		КонецЕсли;
		
		Если ЗначениеЗаполнено(Запрос.Текст) Тогда
			РезультатыЗапроса = Запрос.ВыполнитьПакет();
			Для Каждого РезультатЗапроса Из РезультатыЗапроса Цикл
				
				ОбъектыСТабличнойЧастьюПредставлениеКОбработке = РезультатЗапроса.Выгрузить().ВыгрузитьКолонку("Ссылка");
				ОбщегоНазначенияКлиентСервер.ДополнитьМассив(ОбъектыКОбработке, 
					ОбъектыСТабличнойЧастьюПредставлениеКОбработке, Истина);
			КонецЦикла;
		КонецЕсли;
		
	КонецЕсли;
	
	Возврат ОбъектыКОбработке;
	
КонецФункции

#Область ИзменениеЯзыка

// Данные для изменения мультиязычных реквизитов.
// 
// Возвращаемое значение:
//  Структура:
//   * НастройкиИзмененияЯзыков - см. МультиязычностьСервер.ОписаниеСтарыхИНовыхНастроекЯзыков
//   * ОсновнойЯзыкИзменен - Булево
//   * ПервыйДополнительныйЯзыкИзменен - Булево
//   * ВторойДополнительныйЯзыкИзменен - Булево
//   * Объекты - Соответствие из КлючИЗначение:
//   ** Ключ - Строка
//   ** Значение - Структура:
//     *** СсылкаНаПоследнийОбработанныйОбъекты - Произвольный
//    *** ЯзыковыеПоля - Массив
//	
Функция ДанныеДляИзмененияМультиязычныхРеквизитов() Экспорт

	Если Метаданные.Языки.Количество() = 1 
		Или (ОбщегоНазначения.РазделениеВключено() 
		   И ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных()) Тогда
		Возврат Неопределено;
	КонецЕсли;

	ДанныеДляИзмененияМультиязычныхРеквизитов = Константы.ДанныеДляИзмененияМультиязычныхРеквизитов.Получить().Получить();
	Если ДанныеДляИзмененияМультиязычныхРеквизитов = Неопределено Тогда
		Возврат Неопределено;
	КонецЕсли;
	
	НастройкиИзмененияЯзыков = ДанныеДляИзмененияМультиязычныхРеквизитов.НастройкиИзмененияЯзыков;
	ДанныеДляИзмененияМультиязычныхРеквизитов.Вставить("ОсновнойЯзыкИзменен", 
		СтрСравнить(НастройкиИзмененияЯзыков.ОсновнойЯзыкНовоеЗначение, НастройкиИзмененияЯзыков.ОсновнойЯзыкСтароеЗначение) <> 0);
	ДанныеДляИзмененияМультиязычныхРеквизитов.Вставить("ПервыйДополнительныйЯзыкИзменен", 
		СтрСравнить(НастройкиИзмененияЯзыков.ДополнительныйЯзык1НовоеЗначение, НастройкиИзмененияЯзыков.ДополнительныйЯзык1СтароеЗначение) <> 0);
	ДанныеДляИзмененияМультиязычныхРеквизитов.Вставить("ВторойДополнительныйЯзыкИзменен",
		СтрСравнить(НастройкиИзмененияЯзыков.ДополнительныйЯзык2НовоеЗначение, НастройкиИзмененияЯзыков.ДополнительныйЯзык2СтароеЗначение) <> 0);
		
	Возврат ДанныеДляИзмененияМультиязычныхРеквизитов;

КонецФункции

Процедура ИзменитьЯзыкВМультиязычныхРеквизитахКонфигурации(Параметры, Адрес) Экспорт
	
	ДанныеДляИзмененияМультиязычныхРеквизитов = ДанныеДляИзмененияМультиязычныхРеквизитов();
	Если ДанныеДляИзмененияМультиязычныхРеквизитов = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	ОбъектыСНачальнымЗаполнением = ОбновлениеИнформационнойБазыСлужебный.ОбъектыСНачальнымЗаполнением();
	
	Для Каждого ДанныеОбъекта Из ДанныеДляИзмененияМультиязычныхРеквизитов.Объекты Цикл
		ПолноеИмя = ДанныеОбъекта.Ключ;
		МетаданныеОбъекта = ОбщегоНазначения.ОбъектМетаданныхПоПолномуИмени(ПолноеИмя);
		ПараметрыЗаполнения = Новый Структура;
		
		Если ОбъектыСНачальнымЗаполнением.Найти(МетаданныеОбъекта) <> Неопределено Тогда
			
			ПараметрыЗаполнения = ОбновлениеИнформационнойБазыСлужебный.НаборПараметровДляЗаполненияОбъекта(МетаданныеОбъекта);
			
		КонецЕсли;
		
		Если СтрНачинаетсяС(ПолноеИмя, "Справочник")
			Или СтрНачинаетсяС(ПолноеИмя, "ПланВидовХарактеристик") Тогда
			
			// @skip-check query-in-loop - Порционная обработка больших объемов данных.
			ОбработатьСсылочныеОбъекты(ПолноеИмя, ДанныеОбъекта.Значение, ДанныеДляИзмененияМультиязычныхРеквизитов, ПараметрыЗаполнения);
				
		ИначеЕсли СтрНачинаетсяС(ПолноеИмя, "РегистрСведений") Тогда
			ОбъектМетаданных = ОбщегоНазначения.ОбъектМетаданныхПоПолномуИмени(ПолноеИмя);
			
			Если ОбъектМетаданных.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.ПодчинениеРегистратору Тогда
				// @skip-check query-in-loop - Порционная обработка больших объемов данных.
				ИзменитьЯзыкВПодчиненныхРегистрахСведений(ОбъектМетаданных, ДанныеОбъекта.Значение, ДанныеДляИзмененияМультиязычныхРеквизитов, ПараметрыЗаполнения);
			Иначе
				Периодический = ОбъектМетаданных.ПериодичностьРегистраСведений <> Метаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.Непериодический;
				// @skip-check query-in-loop - Порционная обработка больших объемов данных.
				ИзменитьЯзыкВНезависимыхРегистрахСведений(ОбъектМетаданных, ДанныеОбъекта.Значение, ДанныеДляИзмененияМультиязычныхРеквизитов, ПараметрыЗаполнения, Периодический);
			КонецЕсли;
			
		КонецЕсли;
	
	КонецЦикла;
	
	Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ВариантыОтчетов") Тогда
		МодульВариантыОтчетов = ОбщегоНазначения.ОбщийМодуль("ВариантыОтчетов");
		Настройки = МодульВариантыОтчетов.ПараметрыОбновленияНастроек();
		Настройки.Отложенное = Истина;
		МодульВариантыОтчетов.Обновить(Настройки);
		МодульВариантыОтчетов.СброситьЗаполнениеПредставлений("ОбщиеДанныеКонфигурации");
	КонецЕсли;

КонецПроцедуры

Процедура ОбработатьСсылочныеОбъекты(ПолноеИмя, ДанныеОбъекта, ДанныеДляИзмененияМультиязычныхРеквизитов, ПараметрыЗаполнения)
	
	ПоследняяСсылка = ?(ДанныеОбъекта.СсылкаНаПоследнийОбработанныйОбъекты <> Неопределено,
	ДанныеОбъекта.СсылкаНаПоследнийОбработанныйОбъекты,
	ОбщегоНазначения.МенеджерОбъектаПоПолномуИмени(ПолноеИмя).ПустаяСсылка());
	
	ШаблонПолейЗапроса = "ДанныеОбъекта.%1%2 КАК %1%2";
	
	ЗначенияЯзыковыхКонстант = ДанныеДляИзмененияМультиязычныхРеквизитов.НастройкиИзмененияЯзыков;
	МультиязычныеРеквизиты = ДанныеОбъекта.ЯзыковыеПоля;
	
	ЕстьПорцияДанных = Истина;
	
	ОбъектСодержитТЧПредставления = Ложь;
	Если ПараметрыЗаполнения.Количество() > 0 Тогда
		ОбъектСодержитТЧПредставления =  ПараметрыЗаполнения.ОбъектСодержитТЧПредставления;
	КонецЕсли;
	
	Пока ЕстьПорцияДанных Цикл

		ПоляЗапроса = Новый Массив;

		Для Каждого МультиязычныйРеквизит Из МультиязычныеРеквизиты Цикл

			ПоляЗапроса.Добавить(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				ШаблонПолейЗапроса, МультиязычныйРеквизит, ""));
			ПоляЗапроса.Добавить(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				ШаблонПолейЗапроса, МультиязычныйРеквизит, СуффиксПервогоЯзыка()));
			ПоляЗапроса.Добавить(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				ШаблонПолейЗапроса, МультиязычныйРеквизит, СуффиксВторогоЯзыка()));

		КонецЦикла;

		Запрос = Новый Запрос;
		ТекстЗапроса =
		"ВЫБРАТЬ ПЕРВЫЕ 1000
		|	ДанныеОбъекта.Ссылка КАК Ссылка,
		|	&ПолеОбъекта
		|ИЗ
		|	#ДанныеОбъекта КАК ДанныеОбъекта
		|ГДЕ
		|	ДанныеОбъекта.Ссылка > &Ссылка
		|
		|УПОРЯДОЧИТЬ ПО
		|	Ссылка";

		ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ПолеОбъекта", СтрСоединить(ПоляЗапроса, "," + Символы.ПС));
		ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "#ДанныеОбъекта", ПолноеИмя);

		Запрос.Текст = ТекстЗапроса;
		Запрос.УстановитьПараметр("Ссылка", ПоследняяСсылка);
		
		// @skip-check query-in-loop - Порционная обработка данных
		РезультатЗапроса = Запрос.Выполнить();
		
		Если Не РезультатЗапроса.Пустой() Тогда

			ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();

			Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

				НачатьТранзакцию();
				Попытка

					Блокировка = Новый БлокировкаДанных;
					ЭлементБлокировки = Блокировка.Добавить(ПолноеИмя);
					ЭлементБлокировки.УстановитьЗначение("Ссылка", ВыборкаДетальныеЗаписи.Ссылка);
					Блокировка.Заблокировать();

					ИзменяемыйОбъект = ВыборкаДетальныеЗаписи.Ссылка.ПолучитьОбъект();
					Если ИзменяемыйОбъект = Неопределено Тогда // объект может быть уже удален в других сеансах
						ОтменитьТранзакцию();
						Продолжить;
					КонецЕсли;
					
					ЗаблокироватьДанныеДляРедактирования(ВыборкаДетальныеЗаписи.Ссылка);
					
					НоваяСтрокаТЧПредставления = Неопределено;
					
					Для Каждого МультиязычныйРеквизит Из МультиязычныеРеквизиты Цикл
						
						// Сохраняем старые значения
						ЗначенияРеквизита = Новый Соответствие;
						ЗначенияРеквизита[ЗначенияЯзыковыхКонстант.ОсновнойЯзыкСтароеЗначение] =  ИзменяемыйОбъект[МультиязычныйРеквизит];
						ЗначенияРеквизита[ЗначенияЯзыковыхКонстант.ДополнительныйЯзык1СтароеЗначение] = ИзменяемыйОбъект[МультиязычныйРеквизит + СуффиксПервогоЯзыка()];
						ЗначенияРеквизита[ЗначенияЯзыковыхКонстант.ДополнительныйЯзык2СтароеЗначение] = ИзменяемыйОбъект[МультиязычныйРеквизит + СуффиксВторогоЯзыка()];
							
						ЗначениеПоУмолчанию = ИзменяемыйОбъект[МультиязычныйРеквизит];
						Если ДанныеДляИзмененияМультиязычныхРеквизитов.ОсновнойЯзыкИзменен Тогда
							НовоеЗначение = ЗначенияРеквизита[ЗначенияЯзыковыхКонстант.ОсновнойЯзыкНовоеЗначение];
							ЗаполнитьРеквизитИТЧПредставления(ПараметрыЗаполнения, МультиязычныйРеквизит, ИзменяемыйОбъект, НовоеЗначение, ЗначениеПоУмолчанию,
								ЗначенияЯзыковыхКонстант.ОсновнойЯзыкНовоеЗначение);
								
							Если ОбъектСодержитТЧПредставления Тогда
								Отбор = Новый Структура("КодЯзыка", ЗначенияЯзыковыхКонстант.ОсновнойЯзыкНовоеЗначение);
								НайденныеСтроки = ИзменяемыйОбъект.Представления.НайтиСтроки(Отбор);
								Для каждого НайденнаяСтрока Из НайденныеСтроки Цикл
									ИзменяемыйОбъект.Представления.Удалить(НайденнаяСтрока);
								КонецЦикла;
								
								Если ЗначениеЗаполнено(ЗначенияЯзыковыхКонстант.ОсновнойЯзыкСтароеЗначение) Тогда
									
									Если ПараметрыЗаполнения.ПоддерживаетсяИерархия 
										И ИзменяемыйОбъект.ЭтоГруппа
										И НЕ ПараметрыЗаполнения.ТЧПредставленияИспользуетсяДляГрупп Тогда
										Продолжить;
									КонецЕсли;
									
									Отбор = Новый Структура("КодЯзыка", ЗначенияЯзыковыхКонстант.ОсновнойЯзыкСтароеЗначение);
									НайденныеСтроки = ИзменяемыйОбъект.Представления.НайтиСтроки(Отбор);
									Если НайденныеСтроки.Количество() > 0 Тогда
										СтрокаДанных = НайденныеСтроки[0];
									Иначе
										СтрокаДанных= ИзменяемыйОбъект.Представления.Добавить();
										СтрокаДанных.КодЯзыка= ЗначенияЯзыковыхКонстант.ОсновнойЯзыкСтароеЗначение;
									КонецЕсли;
									СтрокаДанных[МультиязычныйРеквизит] = ЗначенияРеквизита[ЗначенияЯзыковыхКонстант.ОсновнойЯзыкСтароеЗначение];
								КонецЕсли;
								
							КонецЕсли;
							
						КонецЕсли;
						
						Если ДанныеДляИзмененияМультиязычныхРеквизитов.ПервыйДополнительныйЯзыкИзменен Тогда
							НовоеЗначение = ЗначенияРеквизита[ЗначенияЯзыковыхКонстант.ДополнительныйЯзык1НовоеЗначение];
							ЗаполнитьРеквизитИТЧПредставления(ПараметрыЗаполнения, МультиязычныйРеквизит, ИзменяемыйОбъект, НовоеЗначение, ЗначениеПоУмолчанию,
								ЗначенияЯзыковыхКонстант.ДополнительныйЯзык1НовоеЗначение);
								
						КонецЕсли;
						
						Если ДанныеДляИзмененияМультиязычныхРеквизитов.ВторойДополнительныйЯзыкИзменен Тогда
							НовоеЗначение = ЗначенияРеквизита[ЗначенияЯзыковыхКонстант.ДополнительныйЯзык2НовоеЗначение];
							ЗаполнитьРеквизитИТЧПредставления(ПараметрыЗаполнения, МультиязычныйРеквизит, ИзменяемыйОбъект, НовоеЗначение, ЗначениеПоУмолчанию,
								ЗначенияЯзыковыхКонстант.ДополнительныйЯзык2НовоеЗначение);
						КонецЕсли;
						
						Если НоваяСтрокаТЧПредставления <> Неопределено Тогда
							НоваяСтрокаТЧПредставления[МультиязычныйРеквизит] = ЗначенияРеквизита[ЗначенияЯзыковыхКонстант.ОсновнойЯзыкСтароеЗначение];
						КонецЕсли;
						
					КонецЦикла;
					
					ОбновлениеИнформационнойБазы.ЗаписатьОбъект(ИзменяемыйОбъект);
					
					ПоследняяСсылка = ВыборкаДетальныеЗаписи.Ссылка;
					ДанныеОбъекта.СсылкаНаПоследнийОбработанныйОбъекты = ПоследняяСсылка;
					
					ЗаписатьДанныеДляИзмененияМультиязычныхРеквизитов(ДанныеДляИзмененияМультиязычныхРеквизитов);
					
					ЗафиксироватьТранзакцию();
					
				Исключение
					ОтменитьТранзакцию();
					ВызватьИсключение;
				КонецПопытки;
			
			КонецЦикла;
			
		Иначе
			ЕстьПорцияДанных = Ложь;
			
			ДанныеДляИзмененияМультиязычныхРеквизитов.Объекты.Удалить(ПолноеИмя);
			ЗаписатьДанныеДляИзмененияМультиязычныхРеквизитов(ДанныеДляИзмененияМультиязычныхРеквизитов);
			
			Возврат;
		КонецЕсли;

	КонецЦикла;
		
КонецПроцедуры

Процедура ЗаполнитьРеквизитИТЧПредставления(ПараметрыЗаполнения, МультиязычныйРеквизит, ИзменяемыйОбъект, НовоеЗначение, ЗначениеПоУмолчанию, КодЯзыка = "")
	
	ЗначениеЗаполнения = "";
	ЕстьПараметрыЗаполнения  = ПараметрыЗаполнения.Количество() <> 0;
	ОбъектСодержитТЧПредставления = ?(ЕстьПараметрыЗаполнения,
		ПараметрыЗаполнения.ОбъектСодержитТЧПредставления,Ложь);
	
	Если НовоеЗначение <> Неопределено Тогда
		ЗначениеЗаполнения = НовоеЗначение;
	ИначеЕсли ОбъектСодержитТЧПредставления Тогда
		
		Отбор = Новый Структура("КодЯзыка", КодЯзыка);
		НайтиСтроки = ИзменяемыйОбъект.Представления.НайтиСтроки(Отбор);
		Если НайтиСтроки.Количество() > 0 Тогда
			ЗначениеЗаполнения = НайтиСтроки[0][МультиязычныйРеквизит];
		КонецЕсли;
		
	КонецЕсли;
	
	Если ПустаяСтрока(ЗначениеЗаполнения) И ЕстьПараметрыЗаполнения Тогда
		ЗначениеЗаполнения = НачальноеЗначениеРеквизита(ПараметрыЗаполнения, МультиязычныйРеквизит, ИзменяемыйОбъект, КодЯзыка);
	КонецЕсли;
	
	ЗначениеЗаполнения = ?(ЗначениеЗаполнено(ЗначениеЗаполнения),
		ЗначениеЗаполнения, ЗначениеПоУмолчанию);
	
	Если ПустаяСтрока(ЗначениеЗаполнения)  Тогда
		Возврат;
	КонецЕсли;
	
	СуффиксЯзыка = СуффиксЯзыка(КодЯзыка);
	Если ЗначениеЗаполнено(СуффиксЯзыка) Тогда
		ИзменяемыйОбъект[МультиязычныйРеквизит + СуффиксЯзыка] = ЗначениеЗаполнения;
	ИначеЕсли СтрСравнить(ОбщегоНазначения.КодОсновногоЯзыка(), КодЯзыка) = 0 Тогда
		ИзменяемыйОбъект[МультиязычныйРеквизит] = ЗначениеЗаполнения;
	КонецЕсли;
	
	Если ПустаяСтрока(КодЯзыка) 
		Или Не ОбъектСодержитТЧПредставления
		Или (ПараметрыЗаполнения.ПоддерживаетсяИерархия И ИзменяемыйОбъект.ЭтоГруппа) Тогда
		Возврат;
	КонецЕсли;
	
	Отбор = Новый Структура("КодЯзыка", КодЯзыка);
	НайтиСтроки = ИзменяемыйОбъект.Представления.НайтиСтроки(Отбор);
	Если НайтиСтроки.Количество() > 0 Тогда
		
		СтрокаТекущегоЯзыка = НайтиСтроки[0];
		
	Иначе
		
		СтрокаТекущегоЯзыка = ИзменяемыйОбъект.Представления.Добавить();
		СтрокаТекущегоЯзыка.КодЯзыка = КодЯзыка;
		
	КонецЕсли;
	
	СтрокаТекущегоЯзыка[МультиязычныйРеквизит] = ЗначениеЗаполнения;
	
КонецПроцедуры

Функция НачальноеЗначениеРеквизита(ПараметрыЗаполнения, МультиязычныйРеквизит, ИзменяемыйОбъект, КодЯзыка)
	
	ЗначениеЗаполнения = "";
	
	Если ПараметрыЗаполнения.ПредопределенныеДанные.Количество() > 0 Тогда
	
		ДанныеЗаполнения = Неопределено;
		
		Настройки = ПараметрыЗаполнения.НастройкиПредопределенныхЭлементов;
		
		ИмяКлючевогоРеквизита = Настройки.ПереопределяемыеНастройки.ИмяКлючевогоРеквизита;
		ЗначениеКлючевогоРеквизита = ИзменяемыйОбъект[ИмяКлючевогоРеквизита];
		Если ЗначениеЗаполнено(ЗначениеКлючевогоРеквизита) Тогда
			ДанныеЗаполнения = ПараметрыЗаполнения.ПредопределенныеДанные.Найти(ЗначениеКлючевогоРеквизита, ИмяКлючевогоРеквизита);
			
		ИначеЕсли Настройки.ЕстьКолонкаИмяПредопределенныхДанных Тогда
			ЗначениеКлючевогоРеквизита  = ИзменяемыйОбъект["ИмяПредопределенныхДанных"];
			ДанныеЗаполнения = ПараметрыЗаполнения.ПредопределенныеДанные.Найти(ЗначениеКлючевогоРеквизита, "ИмяПредопределенныхДанных");
		КонецЕсли;
		
		Если ТипЗнч(ДанныеЗаполнения) = Тип("СтрокаТаблицыЗначений") Тогда
			
			ЗначениеЗаполнения = ?(ЗначениеЗаполнено(КодЯзыка), ДанныеЗаполнения[МультиязычныйРеквизит + "_" + КодЯзыка],
				ДанныеЗаполнения[МультиязычныйРеквизит]);
			
		КонецЕсли;
		
	КонецЕсли;
	
	Возврат ЗначениеЗаполнения;
	
КонецФункции

Процедура ЗаписатьДанныеДляИзмененияМультиязычныхРеквизитов(ДанныеДляИзмененияМультиязычныхРеквизитов)
	
	УстановитьПривилегированныйРежим(Истина);
	Если ДанныеДляИзмененияМультиязычныхРеквизитов.Объекты.Количество() = 0 Тогда
		УпакованноеЗначение = Неопределено;
	Иначе
		УпакованноеЗначение = Новый ХранилищеЗначения(ДанныеДляИзмененияМультиязычныхРеквизитов);
	КонецЕсли;
	
	Константы.ДанныеДляИзмененияМультиязычныхРеквизитов.Установить(УпакованноеЗначение);

КонецПроцедуры

Процедура ИзменитьЯзыкВПодчиненныхРегистрахСведений(ОбъектМетаданных, ДанныеОбъекта, ДанныеДляИзмененияМультиязычныхРеквизитов, ПараметрыЗаполнения, Периодический = Ложь)
	
	ПолноеИмя = ОбъектМетаданных.ПолноеИмя(); 
	МенеджерРегистра = ОбщегоНазначения.МенеджерОбъектаПоПолномуИмени(ПолноеИмя);
	
	МультиязычныеРеквизиты = ДанныеОбъекта.ЯзыковыеПоля;
	ЗначенияЯзыковыхКонстант = ДанныеДляИзмененияМультиязычныхРеквизитов.НастройкиИзмененияЯзыков;
	
	ИмяТаблицы = СтрЗаменить(ПолноеИмя, ".", "");
	
	ТекстЗапроса = "ВЫБРАТЬ РАЗЛИЧНЫЕ ПЕРВЫЕ 1000
	|	ИмяТаблицы.Регистратор КАК РегистраторРеквизитСсылка
	|ИЗ
	|	&ОбъектМетаданных КАК ИмяТаблицы
	|ГДЕ
	|	ИмяТаблицы.Регистратор > &Регистратор
	|УПОРЯДОЧИТЬ ПО
	|	ИмяТаблицы.Регистратор";

	ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ОбъектМетаданных", ПолноеИмя);
	ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "ИмяТаблицы", ИмяТаблицы);
	
	Запрос = Новый Запрос(ТекстЗапроса);
	Если ДанныеОбъекта.СсылкаНаПоследнийОбработанныйОбъекты = Неопределено Тогда
		Запрос.УстановитьПараметр("Регистратор", Неопределено);
	Иначе
		Отбор = ДанныеОбъекта.СсылкаНаПоследнийОбработанныйОбъекты;
		Запрос.УстановитьПараметр("Регистратор", Отбор["Регистратор"]);
	КонецЕсли;
	
	Результат = Запрос.Выполнить().Выгрузить();
	
	Пока Результат.Количество() > 0 Цикл
		
		Для Каждого СтрокаРезультата Из Результат Цикл
			
			Блокировка = Новый БлокировкаДанных;
			ЭлементБлокировки = Блокировка.Добавить(ПолноеИмя + "." + "НаборЗаписей");
			
			ТекущийНаборЗаписей = МенеджерРегистра.СоздатьНаборЗаписей();
			ТекущийНаборЗаписей.Отбор.Регистратор.Установить(СтрокаРезультата.РегистраторРеквизитСсылка);
			
			ЭлементБлокировки.УстановитьЗначение("Регистратор", СтрокаРезультата.РегистраторРеквизитСсылка);
			
			НачатьТранзакцию();
				Попытка
					
					Блокировка.Заблокировать();
					ТекущийНаборЗаписей.Прочитать();
					
					Если ТекущийНаборЗаписей.Количество() = 0 Тогда
						ОтменитьТранзакцию();
						Продолжить;
					КонецЕсли;
					
					Для Каждого ИзменяемаяЗапись Из ТекущийНаборЗаписей Цикл
						
						Для Каждого МультиязычныйРеквизит Из МультиязычныеРеквизиты Цикл
							
							// Сохраняем старые значения
							ЗначенияРеквизита = Новый Соответствие;
							ЗначенияРеквизита[ЗначенияЯзыковыхКонстант.ОсновнойЯзыкСтароеЗначение] =  ИзменяемаяЗапись[МультиязычныйРеквизит];
							ЗначенияРеквизита[ЗначенияЯзыковыхКонстант.ДополнительныйЯзык1СтароеЗначение] = ИзменяемаяЗапись[МультиязычныйРеквизит + СуффиксПервогоЯзыка()];
							ЗначенияРеквизита[ЗначенияЯзыковыхКонстант.ДополнительныйЯзык2СтароеЗначение] = ИзменяемаяЗапись[МультиязычныйРеквизит + СуффиксВторогоЯзыка()];
							
							ЗначениеПоУмолчанию = Строка(ИзменяемаяЗапись[МультиязычныйРеквизит]);
							Если ДанныеДляИзмененияМультиязычныхРеквизитов.ОсновнойЯзыкИзменен Тогда
								НовоеЗначение = ЗначенияРеквизита[ЗначенияЯзыковыхКонстант.ОсновнойЯзыкНовоеЗначение];
								ЗаполнитьРеквизитИТЧПредставления(ПараметрыЗаполнения, МультиязычныйРеквизит, ИзменяемаяЗапись, НовоеЗначение, ЗначениеПоУмолчанию,
									ЗначенияЯзыковыхКонстант.ОсновнойЯзыкНовоеЗначение);
							КонецЕсли;
							
							Если ДанныеДляИзмененияМультиязычныхРеквизитов.ПервыйДополнительныйЯзыкИзменен Тогда
								НовоеЗначение = ЗначенияРеквизита[ЗначенияЯзыковыхКонстант.ДополнительныйЯзык1НовоеЗначение];
								ЗаполнитьРеквизитИТЧПредставления(ПараметрыЗаполнения, МультиязычныйРеквизит, ИзменяемаяЗапись, НовоеЗначение, ЗначениеПоУмолчанию,
									ЗначенияЯзыковыхКонстант.ДополнительныйЯзык1НовоеЗначение);
							КонецЕсли;
							
							Если ДанныеДляИзмененияМультиязычныхРеквизитов.ВторойДополнительныйЯзыкИзменен Тогда
								НовоеЗначение = ЗначенияРеквизита[ЗначенияЯзыковыхКонстант.ДополнительныйЯзык2НовоеЗначение];
								ЗаполнитьРеквизитИТЧПредставления(ПараметрыЗаполнения, МультиязычныйРеквизит, ИзменяемаяЗапись, НовоеЗначение, ЗначениеПоУмолчанию,
									ЗначенияЯзыковыхКонстант.ДополнительныйЯзык2НовоеЗначение);
							КонецЕсли;
							
						КонецЦикла;
						
					КонецЦикла;
					
					ОбновлениеИнформационнойБазы.ЗаписатьДанные(ТекущийНаборЗаписей);
					
					Отбор = Новый Структура();
					Отбор.Вставить("Регистратор", СтрокаРезультата.РегистраторРеквизитСсылка);
					
					ДанныеОбъекта.СсылкаНаПоследнийОбработанныйОбъекты = Отбор;
					
					ЗаписатьДанныеДляИзмененияМультиязычныхРеквизитов(ДанныеДляИзмененияМультиязычныхРеквизитов);
					
					ЗафиксироватьТранзакцию();
					
				Исключение
					ОтменитьТранзакцию();
					ВызватьИсключение;
				КонецПопытки;
			
		КонецЦикла;
		
		Запрос.УстановитьПараметр("Регистратор", СтрокаРезультата.РегистраторРеквизитСсылка);
		
		// @skip-check query-in-loop - Порционная обработка данных
		Результат = Запрос.Выполнить().Выгрузить();
		
	КонецЦикла;
	
	ДанныеДляИзмененияМультиязычныхРеквизитов.Объекты.Удалить(ПолноеИмя);
	ЗаписатьДанныеДляИзмененияМультиязычныхРеквизитов(ДанныеДляИзмененияМультиязычныхРеквизитов);
	
КонецПроцедуры

Процедура ИзменитьЯзыкВНезависимыхРегистрахСведений(ОбъектМетаданных, ДанныеОбъекта, ДанныеДляИзмененияМультиязычныхРеквизитов, ПараметрыЗаполнения, Периодический = Ложь)
	
	ПолноеИмя = ОбъектМетаданных.ПолноеИмя(); 
	МенеджерРегистра = ОбщегоНазначения.МенеджерОбъектаПоПолномуИмени(ПолноеИмя);
	
	МультиязычныеРеквизиты = ДанныеОбъекта.ЯзыковыеПоля;
	ЗначенияЯзыковыхКонстант = ДанныеДляИзмененияМультиязычныхРеквизитов.НастройкиИзмененияЯзыков;
	
	ИмяТаблицы = СтрЗаменить(ПолноеИмя, ".", "");
	ШаблонПолейВыборки = "ИмяТаблицы.[ИмяПоля] КАК [ИмяПоля]ИзмерениеСсылка";
	
	Измерения          = ОбъектМетаданных.Измерения;// Массив из ОбъектМетаданныхИзмерение
	
	НаборПолейВыборки        = Новый Массив;
	НаборУсловий             = Новый Массив;
	НаборПолейУпорядочивания = Новый Массив;
	
	Если Периодический Тогда
		НаборПолейУпорядочивания.Добавить(ИмяТаблицы + "." + "Период");
		НаборУсловий.Добавить("ИмяТаблицы.Период > &Период");
		НаборПолейВыборки.Добавить("ИмяТаблицы.Период КАК Период");
	КонецЕсли;
	
	Для Каждого Измерение Из Измерения Цикл
		НаборДополнительныхУсловий = Новый Массив;
		
		Если НаборУсловий.Количество() > 0 Тогда
			НаборДополнительныхУсловий.Добавить(СтрЗаменить(НаборУсловий.Получить(НаборУсловий.ВГраница()), ">", "="));
		КонецЕсли;
		НаборДополнительныхУсловий.Добавить(ИмяТаблицы + "." + Измерение.Имя + " > &" + Измерение.Имя);
		
		НаборУсловий.Добавить(СтрСоединить(НаборДополнительныхУсловий, " И "));
		
		НаборПолейУпорядочивания.Добавить(ИмяТаблицы + "." + Измерение.Имя);
		НаборПолейВыборки.Добавить(СтрЗаменить(ШаблонПолейВыборки, "[ИмяПоля]", Измерение.Имя));
		
	КонецЦикла;
	
	УсловиеПоИзмерениям = СтрСоединить(НаборУсловий, " ИЛИ ");
	ПоляУпорядочивания  = СтрСоединить(НаборПолейУпорядочивания, ", " + Символы.ПС);
	ПоляВыборки         = СтрСоединить(НаборПолейВыборки, ", " + Символы.ПС);
	
	ТекстЗапроса =
	"ВЫБРАТЬ ПЕРВЫЕ 1000
	|	&ПоляВыборки КАК ПоляВыборки
	|ИЗ
	|	&ОбъектМетаданных КАК ИмяТаблицы
	|ГДЕ
	|	&Условие
	|
	|УПОРЯДОЧИТЬ ПО
	|	&ПоляУпорядочивания";
	
	ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&Условие", УсловиеПоИзмерениям);

	ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ПоляУпорядочивания", ПоляУпорядочивания);
	ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ПоляВыборки КАК ПоляВыборки", ПоляВыборки);
	ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ОбъектМетаданных", ПолноеИмя);
	ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "ИмяТаблицы", ИмяТаблицы);
		
	Запрос = Новый Запрос(ТекстЗапроса);
	Если ДанныеОбъекта.СсылкаНаПоследнийОбработанныйОбъекты = Неопределено Тогда
		
		Если Периодический Тогда
			Запрос.УстановитьПараметр("Период", Дата("00010101"));
			
		КонецЕсли;
		Для Каждого Измерение Из Измерения Цикл
			Запрос.УстановитьПараметр(Измерение.Имя, Неопределено);
		КонецЦикла;
		
	Иначе
		Отбор = ДанныеОбъекта.СсылкаНаПоследнийОбработанныйОбъекты;
		
		Для Каждого Измерение Из Измерения Цикл
			Запрос.УстановитьПараметр(Измерение.Имя, Отбор[Измерение.Имя]);
		КонецЦикла;
		
		Если Периодический Тогда
			Запрос.УстановитьПараметр("Период", Отбор["Период"]);
		КонецЕсли;
	
	КонецЕсли;
	
	Результат = Запрос.Выполнить().Выгрузить();
	
	Пока Результат.Количество() > 0 Цикл
		
		Для Каждого СтрокаРезультата Из Результат Цикл
			
			Блокировка = Новый БлокировкаДанных;
			ЭлементБлокировки = Блокировка.Добавить(ПолноеИмя);
		
			
			ТекущийНаборЗаписей = МенеджерРегистра.СоздатьНаборЗаписей();
			ОтборТекущегоНабора = ТекущийНаборЗаписей.Отбор;
			
			Если Периодический Тогда
				ЭлементБлокировки.УстановитьЗначение("Период", СтрокаРезультата["Период"]);
				ОтборТекущегоНабора.Период.Установить(СтрокаРезультата["Период"]);
			КонецЕсли;
			
			Для Каждого Измерение Из Измерения Цикл
				
				ИмяИзмерения      = Измерение.Имя;
				ЗначениеИзмерения = СтрокаРезультата[ИмяИзмерения + "ИзмерениеСсылка"];
				Если Не ЗначениеЗаполнено(ЗначениеИзмерения) Тогда
					Продолжить;
				КонецЕсли;
				
				ОтборПоИзмерению = ОтборТекущегоНабора[ИмяИзмерения];// ЭлементОтбора
				ОтборПоИзмерению.Установить(ЗначениеИзмерения);
				
				ЭлементБлокировки.УстановитьЗначение(ИмяИзмерения, ЗначениеИзмерения);
				
			КонецЦикла;
			
			ОписаниеКлючаЗаписи = ОбщегоНазначения.СтрокаТаблицыЗначенийВСтруктуру(СтрокаРезультата);
			КлючЗаписи = МенеджерРегистра.СоздатьКлючЗаписи(ОписаниеКлючаЗаписи);
			
			НачатьТранзакцию();
				Попытка
					
					Блокировка.Заблокировать();
					ТекущийНаборЗаписей.Прочитать();
					ЗаблокироватьДанныеДляРедактирования(КлючЗаписи);
					
					Если ТекущийНаборЗаписей.Количество() = 0 Тогда
						ОтменитьТранзакцию();
						Продолжить;
					КонецЕсли;
					
					ИзменяемаяЗапись = ТекущийНаборЗаписей.Получить(0);
					
					Для Каждого МультиязычныйРеквизит Из МультиязычныеРеквизиты Цикл
						
						// Сохраняем старые значения
						ЗначенияРеквизита = Новый Соответствие;
						ЗначенияРеквизита[ЗначенияЯзыковыхКонстант.ОсновнойЯзыкСтароеЗначение] =  ИзменяемаяЗапись[МультиязычныйРеквизит];
						ЗначенияРеквизита[ЗначенияЯзыковыхКонстант.ДополнительныйЯзык1СтароеЗначение] = ИзменяемаяЗапись[МультиязычныйРеквизит + СуффиксПервогоЯзыка()];
						ЗначенияРеквизита[ЗначенияЯзыковыхКонстант.ДополнительныйЯзык2СтароеЗначение] = ИзменяемаяЗапись[МультиязычныйРеквизит + СуффиксВторогоЯзыка()];
							
						ЗначениеПоУмолчанию = ИзменяемаяЗапись[МультиязычныйРеквизит];
						Если ДанныеДляИзмененияМультиязычныхРеквизитов.ОсновнойЯзыкИзменен Тогда
							НовоеЗначение = ЗначенияРеквизита[ЗначенияЯзыковыхКонстант.ОсновнойЯзыкНовоеЗначение];
							ЗаполнитьРеквизитИТЧПредставления(ПараметрыЗаполнения, МультиязычныйРеквизит, ИзменяемаяЗапись, НовоеЗначение, ЗначениеПоУмолчанию,
								ЗначенияЯзыковыхКонстант.ОсновнойЯзыкНовоеЗначение);
						КонецЕсли;
						
						Если ДанныеДляИзмененияМультиязычныхРеквизитов.ПервыйДополнительныйЯзыкИзменен Тогда
							НовоеЗначение = ЗначенияРеквизита[ЗначенияЯзыковыхКонстант.ДополнительныйЯзык1НовоеЗначение];
							ЗаполнитьРеквизитИТЧПредставления(ПараметрыЗаполнения, МультиязычныйРеквизит, ИзменяемаяЗапись, НовоеЗначение, ЗначениеПоУмолчанию,
								ЗначенияЯзыковыхКонстант.ДополнительныйЯзык1НовоеЗначение);
						КонецЕсли;
						
						Если ДанныеДляИзмененияМультиязычныхРеквизитов.ВторойДополнительныйЯзыкИзменен Тогда
							НовоеЗначение = ЗначенияРеквизита[ЗначенияЯзыковыхКонстант.ДополнительныйЯзык2НовоеЗначение];
							ЗаполнитьРеквизитИТЧПредставления(ПараметрыЗаполнения, МультиязычныйРеквизит, ИзменяемаяЗапись, НовоеЗначение, ЗначениеПоУмолчанию,
								ЗначенияЯзыковыхКонстант.ДополнительныйЯзык2НовоеЗначение);
						КонецЕсли;
						
					КонецЦикла;
						
					ОбновлениеИнформационнойБазы.ЗаписатьДанные(ТекущийНаборЗаписей);
					
					Отбор = Новый Структура();
					Для Каждого Измерение Из Измерения Цикл
						Отбор.Вставить(Измерение.Имя, СтрокаРезультата[Измерение.Имя + "ИзмерениеСсылка"]);
					КонецЦикла;
					
					Если Периодический Тогда
						Отбор.Вставить("Период", СтрокаРезультата["Период"]);
					КонецЕсли;
					
					ДанныеОбъекта.СсылкаНаПоследнийОбработанныйОбъекты = Отбор;

					ЗаписатьДанныеДляИзмененияМультиязычныхРеквизитов(ДанныеДляИзмененияМультиязычныхРеквизитов);
					
					ЗафиксироватьТранзакцию();
					
				Исключение
					ОтменитьТранзакцию();
					ВызватьИсключение;
				КонецПопытки;
			
		КонецЦикла;
		
		Если Периодический Тогда
			Запрос.УстановитьПараметр("Период", СтрокаРезультата["Период"]);
		КонецЕсли;
		
		Для Каждого Измерение Из Измерения Цикл
			Запрос.УстановитьПараметр(Измерение.Имя, СтрокаРезультата[Измерение.Имя + "ИзмерениеСсылка"]);
		КонецЦикла;
		
		// @skip-check query-in-loop - Порционная обработка данных
		Результат = Запрос.Выполнить().Выгрузить();
		
	КонецЦикла;
	
	ДанныеДляИзмененияМультиязычныхРеквизитов.Объекты.Удалить(ПолноеИмя);
	ЗаписатьДанныеДляИзмененияМультиязычныхРеквизитов(ДанныеДляИзмененияМультиязычныхРеквизитов);
	
КонецПроцедуры

Процедура СкопироватьМультиязычныеЗначенияВРеквизитыШапки(ТекущийОбъект, ИменаЛокализуемыхРеквизитов, КодЯзыка)
	
	СуффиксЯзыка = СуффиксЯзыка(КодЯзыка);
	Если ПустаяСтрока(СуффиксЯзыка) Тогда
		Возврат;
	КонецЕсли;
	
	Представления = ТекущийОбъект.Представления; // ТабличнаяЧасть
	
	Отбор = Новый Структура("КодЯзыка", КодЯзыка);
	
	НайденныеСтроки = Представления.НайтиСтроки(Отбор);
	Если НайденныеСтроки.Количество() > 0 Тогда
		НайденаСтрока = НайденныеСтроки[0];
		Для Каждого Реквизит Из ИменаЛокализуемыхРеквизитов Цикл
			Если ЗначениеЗаполнено(НайденаСтрока[Реквизит.Ключ]) Тогда
				ТекущийОбъект[Реквизит.Ключ + СуффиксЯзыка] = НайденаСтрока[Реквизит.Ключ];
			Иначе
				ТекущийОбъект[Реквизит.Ключ + СуффиксЯзыка] = ТекущийОбъект[Реквизит.Ключ];
			КонецЕсли;
		КонецЦикла;
	Иначе
		Для Каждого Реквизит Из ИменаЛокализуемыхРеквизитов Цикл
			ТекущийОбъект[Реквизит.Ключ + СуффиксЯзыка] = ТекущийОбъект[Реквизит.Ключ];
		КонецЦикла;
	КонецЕсли;
	
КонецПроцедуры


Функция СуффиксПервогоЯзыка() Экспорт
	Возврат "Язык1";
КонецФункции

Функция СуффиксВторогоЯзыка() Экспорт
	Возврат "Язык2";
КонецФункции

Функция ОбъектыСНачальнымЗаполнением(ВариантДанных)
	
	ОбъектыСПредопределеннымиЭлементами = ОбновлениеИнформационнойБазыСлужебный.ОбъектыСНачальнымЗаполнением();
	
	Если Не ОбщегоНазначения.РазделениеВключено()
		Или Не ОбщегоНазначения.ПодсистемаСуществует("ТехнологияСервиса.БазоваяФункциональность") Тогда
		Возврат ОбъектыСПредопределеннымиЭлементами;
	КонецЕсли;
	
	МодульРаботаВМоделиСервиса = ОбщегоНазначения.ОбщийМодуль("РаботаВМоделиСервиса");
	
	Позиция =  ОбъектыСПредопределеннымиЭлементами.Количество() - 1;
	Пока Позиция >= 0 Цикл
		
		ЭтоРазделенныйОбъектМетаданных = МодульРаботаВМоделиСервиса.ЭтоРазделенныйОбъектМетаданных(ОбъектыСПредопределеннымиЭлементами[Позиция]);
		Если ВариантДанных = "Общие" И ЭтоРазделенныйОбъектМетаданных Тогда
			Если ЭтоРазделенныйОбъектМетаданных Тогда
				ОбъектыСПредопределеннымиЭлементами.Удалить(Позиция);
			КонецЕсли;
		ИначеЕсли Не ЭтоРазделенныйОбъектМетаданных Тогда
			ОбъектыСПредопределеннымиЭлементами.Удалить(Позиция);
		КонецЕсли;
		Позиция = Позиция - 1;
	КонецЦикла;
	
	Возврат ОбъектыСПредопределеннымиЭлементами;
	
КонецФункции

#КонецОбласти

#КонецОбласти